iOS 多线程 学习

今天写一篇关于多线程学习的心得体会。
1.先介绍iOS多线程开发的三种方式;
2.再介绍多线程开发应该注意的几个点。

参考:http://www.cnblogs.com/kenshincui/p/3983982.html

iOS 三种多线程:

  • NSThread

  • GCD(Grand Central Dispatch)

  • NSOperation & NSOperationQueue
    以上三种方式,第一种比较轻量级,需要自己管理线程生命周期。第二种和第三种使用了队列来帮助线程的调度,方便了开发者。

  • NSThread
    有两种方式创建:1、显式创建;2、隐式创建。
    1、显式创建:

+(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
-(instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

2、隐式创建:
利用NSObject+NSThreadPerformAdditions中的方法隐式创建NSThread。

-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray *)array;
-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
 // equivalent to the first method with kCFRunLoopCommonModes
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray *)array NS_AVAILABLE(10_5, 2_0);
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
 // equivalent to the first method with kCFRunLoopCommonModes
-(void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);
  • GCD(Grand Central Dispatch)
    GCD是基于C语言开发的一套多线程开发机制。GCD通过管理队列中的操作(block)对线程进行调度,并由队列的种类和分发给队列的操作方式决定线程调度的数量和种类。
    GCD的队列有两种:串行队列和并行队列。
dispatch_get_main_queue();//获取主队列,主队列为串行队列,主队列只会把操作放到主线程中去
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//获取全局并行队列,并行队列会把各种操作放到各个线程中去
dispatch_queue_create(const char *, dispatch_queue_attr_t);//创建一个队列
//第一个参数为队列名称(唯一标识)
//第二个参数为队列类型:
//DISPATCH_QUEUE_SERIAL串行,会将操作放到同一个线程中去
//DISPATCH_QUEUE_CONCURRENT并行,会将操作放到各个线程中去

GCD有两种把操作分发给队列的方式:

dispatch_sync(queue, ^{ //同步操作,队列会将操作放在主线程中执行,会造成线程阻塞 });
dispatch_async(queue, ^{ //异步操作,队列会将操作放在一个新线程中执行,不会造成线程阻塞 });
  • NSOperation & NSOperationQueue
    NSOperation是苹果将GCD进行面向对象的封装,将block操作封装成NSOperation,将队列封装成NSOperationQueue。
    这种多线程使用,要先一个继承于NSOperation的类,并实现几个相关的方法。而苹果还提供了其他两个现成的类:NSInvocationOperation和NSBlockOperation。
//NSInvocationOperation 创建方法
-(NSInvocationOperation *)initWithTarget:selector:object:
//NSBlockOperation 创建方法
+(NSBlockOperation *)blockOperationWithBlock:

在生成NSOperation类后,如果想把操作放到主线程中去,则直接调用NSOperation类的start方法,或者加入到主队列中去;如果想把操作放到其他线程中去执行,则加入到NSOperationQueue队列类中去。

-(void)addOperation:

对于线程的控制,苹果提供了管理NSOperation间的依赖关系,和对NSOperationQueue设置最大并发数等方法,让我们可以更方便地操作多线程。

-(void)addDependency:(NSOperation *)op;
-(void)removeDependency:(NSOperation *)op;

多线程注意事项:

1、对于一切与UI相关的操作,应该放在主队列中(使用同步调用)。
2、简单的线程操作使用NSThread,复杂的线程操作使用其他两方式。而对于需要对线程进行操作的(特别是有取消操作的),优先使用NSOperation。
3、GCD中使用同步调用时会造成阻塞,在阻塞的情况下,容易造成死锁。

你可能感兴趣的:(iOS 多线程 学习)