标签:
多线程是为了解决主线程被阻塞,并提高效率的一种方式.
首先我们要学习多线程编程就要看看它有哪几种方式:
NSThread
NSOperation
Grand Centeral Dispatch
我们看看NSThread的创建方式::
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(btnSum:) object:nil]; //通过iniit 创建NSThread 需要手动开启线程 [thread start]; [thread cancel]; //第二种开启并自动执行 btnSum 是自己写的一个方法 [NSThread detachNewThreadSelector:@selector(btnSum:) toTarget:self withObject:nil];
- (void)btnSum:(UIButton *)sender { long sum = 0; for (long i = 0; i < 10; i ++) { sum += i; NSLog(@"number %ld current Thred : %@ %@",sum,[NSThread currentThread],[NSOperationQueue currentQueue]); } }
使用NSThread 或直接从 NSObject 的类方法 performSelectorInBackground:withObject: 来创建一个线程。如果你选择thread来实现多线程,那么 NSThread 就是官方推荐优先选用的方式
NSOperation
/** NSOperationQueue线程队列 */ // 1.NSInvocationOperation操作 NSInvocationOperation *iOP =[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(btnSum:) object:nil]; //Operation是不能执行的,需要队列进行调用 [[NSOperationQueue mainQueue] addOperation:iOP]; //2.NSBlockOperation NSBlockOperation *bOP = [[NSBlockOperation alloc]init]; //以代码块的方式添加操作 [bOP addExecutionBlock:^{ [self btnSum:nil]; }]; //添加到线程队列 [self.operationQueue addOperation:bOP];
为了创建一个简单的NSOperation对象,直接重写了getter方法
- (NSOperationQueue *)operationQueue{ if (!_operationQueue ) { _operationQueue = [[NSOperationQueue alloc]init]; [_operationQueue setName:@"queue"]; } return _operationQueue; }
//NSBlockOperation 创建方式,可以用便利构造器,直接添加block NSBlockOperation *bOP = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 100; i ++) { NSLog(@"%d,当前线程:::%@",i,[NSThread currentThread]); } }]; NSBlockOperation *aOP = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 100; i ++) { NSLog(@"%d,当前线程:::%@",i,[NSThread currentThread]); } }]; NSBlockOperation *cOP = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 100; i ++) { NSLog(@"%d,当前线程333333333:::%@",i,[NSThread currentThread]); } }]; //添加到主队列 [[NSOperationQueue mainQueue] addOperation:bOP]; [[NSOperationQueue mainQueue] addOperation:cOP]; //自定义队列 self.operation = [[NSOperationQueue alloc]init]; //设置最大并发数 self.operation.maxConcurrentOperationCount = 1;//在同一连续时刻只执行一个操作 // self.operation.maxConcurrentOperationCount = 4; [self performSelectorInBackground:@selector(printNumber:) withObject:@"NSObject"]; [self.operation addOperation:aOP]; [self.operation addOperation:cOP];
GCD
/** GCD 中央派发机制 Grand Central Dispatch 基于函数,使用分发队列FIFO */ //1.主线程队列::等同于[NSOperationQueue mainQueue] //2.全局线程队列 后台队列 并行 //3.自定义线程队列 DISPATCH_QUEUE_SERIAL 串行 // DISPATCH_QUEUE_CONCURRENT 并行 /* //创建自定义队列,默认为串行(故加了个优先级的东东::DISPATCH_QUEUE_PRIORITY_DEFAULT) dispatch_queue_t myQueue = dispatch_queue_create("com.liulei.www.myQueue",DISPATCH_QUEUE_PRIORITY_DEFAULT); //串行队列 // dispatch_async(队列, 执行block) 异步 // dispatch_sync(队列, 执行block)同步 dispatch_async(myQueue, ^{ [self printNumber:@"GCD"]; [self printNumber:@"GCD1"]; }); dispatch_async(myQueue, ^{ [self printNumber:@"GCD2"]; }); */ /* //并行队列 dispatch_queue_t conQueue = dispatch_queue_create("conQueue", DISPATCH_QUEUE_CONCURRENT); //一个bolck中串行 dispatch_async(conQueue, ^{ //顺序执行 [self printNumber:@"G1"]; [self printNumber:@"G2"]; [self printNumber:@"G3"]; }); //并行执行 dispatch_async(conQueue, ^{ [self printNumber:@"G4"]; }); dispatch_async(conQueue, ^{ [self printNumber:@"G5"]; }); */ //dispatch_after ..//延时操作
既然说道多线程的开发,难免会在多线程之间进行通讯;
利用NSObject的一些类方法,可以轻松搞定。(NSObject内置方法来创建线程)
在应用程序主线程中做事情:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array
在指定线程中做事情:
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array
在当前线程中做事情:
//Invokes a method of the receiver on the current thread using the default mode after a delay.
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
performSelector:withObject:afterDelay:inModes:
取消发送给当前线程的某个消息
cancelPreviousPerformRequestsWithTarget:
cancelPreviousPerformRequestsWithTarget:selector:object:
如在我们在某个线程中下载数据,下载完成之后要通知主线程中更新界面等等,可以使用如下接口:-
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
比如下载完成后,通知主线程(ui线程),以便app再做其他工作
标签:
原文地址:http://my.oschina.net/742865703/blog/519043