温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2020-07-18 18:56:39 来源:网络 阅读:1140 作者:iKingLai 栏目:移动开发

如何编写多线程应用


现在你已经知道一个好的多线程应用是怎样的,它是如何帮助你解决问题的,那么如何编写一个好的多线程应用呢?我会向你介绍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 <assert.h>

#include <pthread.h>

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. }];





向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI