iOS使用多线程提高数据并发访问之三

如何编写多线程应用

创新互联公司长期为成百上千客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为门源企业提供专业的成都网站建设、网站制作门源网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。

现在你已经知道一个好的多线程应用是怎样的,它是如何帮助你解决问题的,那么如何编写一个好的多线程应用呢?我会向你介绍iPhone应用中编写和处理多线程应用的主要技术。

创建一个线程

为了创建一个线程,你可以使用下面的方法:

  • NSThread

  • POSIX Threads

  • NSObject 来创建一个新的线程

  • NSOperation和NSOperationQueue

我会逐一介绍他们,然后会举一些例子,因为他们都有各自的优点和缺点。在本部分结束的时候,我会给出一个表格来进行对比,是得你能够分清他们的不同,这样在你的需求中就能够选择一个正确的方案。

NSThread

用NSThread创建一个新的线程,你可以简单的调用:

[NSThread detachNewThreadSelector:@selector(threadMethod:) toTarget:self

withObject:nil];

这个方法会在你的应用中创建一个新的detached线程。一个detached线程就是它的所有资源会被系统回收,当线程存在的时候。

有些属性你需要知道。

+(void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

  • aSelector:当线程开始的时候,这个方法会在目标对象中被调用。根据苹果的文档,这个selector只有一个参数,没有返回值。

  • aTarget:将要执行在aSelector参数中所指定的方法的对象。

  • anArgument:唯一的一个参数;当线程开始的时候,它会被传递到aSelector方法中。


如果你想创建一个线程,但是不想启动它,你可以使用下面的机制:


  1. NSThread* myThread = [[NSThread alloc]initWithTarget:self

    selector:@selector(myThreadMainMethod:)object:nil];

    [myThread start]; // Actually create the thread

你可以看到,第一行,你创建了一个新的线程,然后,根据你的选择,你可以在对象上调用start来启动一个新的线程。这是非常有用的,如果你只想传递myThread对象,而不想传递selector,target和argument的话。

另一个比较好的做法是,使用NSThread对象发送一个消息给线程对象

  1. -(void)performSelector:(SEL)aSelector onThread:(NSThread *)thrwithObject:(id)arg waitUntilDone:(BOOL)wait

这个方法会在另一个线程上queue selector。当系统自动运行线程时,线程会dequeue这个消息,然后会调用aSelector变量指定的方法。

使用POSIX线程

这个在iPhone应用中主要是用c编程时会用到。在第9章,我会更深入的讨论c编程,并能够帮助你在很多情况下提升你的iPhone apps的性能。所以这个部分可能不会帮助你太多,如果你还不了解c编程的话。如果你已经了解了c编程,Listing 6-3 展示了代码,后面会有一个解释。

Listing 6–3.POSIX Thread#include

#include

void* ThreadMethod(void* data){

       // Your main logic comes here.

      return NULL;

}

void LaunchThread(){

       // Create the thread using POSIX routines.

       pthread_attr_t attr;
       pthread_t posixThreadID;
       int returnVal;

       // init and check if init a new thread successful

       returnVal =  pthread_attr_init(&attr);

       assert(!returnVal);

       // set attribute detach state for new thread
       returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

       assert(!returnVal);

       // create and run the new thread
       int threadError = pthread_create(&posixThreadID, &attr, &ThreadMethod, NULL);

       returnVal = pthread_attr_destroy(&attr);

       assert(!returnVal);
       if (threadError != 0)
       {

               // Report an error.

       }

}

NSObject

所有的对象都可以创建和detach一个新的线程来执行这些对象的selectors。你可以使用下面的这行代码在后台线程中运行doSomething方法:

[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];

调用这个方法的效果和下面的这行代码是一样的:

[NSThread detachNewThreadSelector:@selector(doSomething) toTarget:myObj withObject:nil]

这个方法是比较好的,对于detach和创建一个运行后台任务的线程来说。

NSOperationQueue

NSOperationQueue是管理和运行并发任务的一个机制。NSOperationQueue的一个好处是它能够限制系统内部并发operations的数量,通过给定一个限制使得系统加载在一个可以接受的范围水平。因为这个最大线程数量的限制,如果有更多的线程实例,NSOperationQueue不会导致更多的并发线程同时在系统中运行。

你可以在queue中添加operations,但是不能删除。然而,你可以在queue中取消所有已经存在的和还没有运行的operations。表格 6-2 展示了当使用NSOperationQueue时,一些非常有用的方法。

iOS使用多线程提高数据并发访问 之三

你可以用3个不同的类来使用NSOperationQueue。

  • NSInvocationOperation:如果你已经有一个对象和一个方法加入到一个并发线程中,这只是一个简单的包裹。它不需要子类,所以通过这个类来创建一个简单的NSOperation对象。NSInvocationOperation是NSOperation的子类。

  • NSBlockOperation:这是另一包裹类,用来执行一个或多个blocks,而不需要创建一个单独的NSOperation对象来执行每一个block。当执行超过一个block时,只有所有内部的blocks都执行完毕,那么NSBlockOperation才被认为结束了。

  • Custom NSOperation:NSOperation是一个基类。通过继承它,你能够完全的控制整个NSOperation对象的实现,包括你的operation执行说的默认行为和报告它的状态。

使用NSOperationQueue进行多线程设计,你需要用这3个方法中的一个来创建指定的对象,然后把新创建的NSOperation加入到你的queue中。然后这个queue会为你维护和运行这些operations。

这里有一个简单的代码来帮助你创建一个NSOperationQueue,然后把相互独立的operation对象放进去,来创建一个多线程环境:

  1. NSOperationQueue* myOperationQueue = [[NSOperationQueue alloc] init];
    [myOperationQueue addOperation:myOperation]; // Add a single operation
    [myOperationQueue addOperations:arrayOfOperations waitUntilFinished:NO]; // Add multipleoperations
    [aQueue addOperationWithBlock:^{

    /* Do Something. */

  2. }];


文章名称:iOS使用多线程提高数据并发访问之三
文章来源:http://azwzsj.com/article/gidoph.html