iOS多线程编程总结
来源:互联网 发布:java 修改配置文件 编辑:程序博客网 时间:2024/04/29 20:25
摘录:http://www.cnblogs.com/mjios/archive/2013/04/18/3029309.html
http://blog.csdn.net/totogo2010/article/details/8010231
简介
iOS有三种多线程编程的技术,分别是:
1.、NSThread :这种方法需要管理线程的生命周期、同步、加锁问题,会导致一定的性能开销
2、Cocoa NSOperation :是基于OC实现的。NSOperation以面向对象的方式封装了需要执行的操作,然后可以将这个操作放到一个NSOperationQueue中去异步执行。不必关心线程管理、同步等问题。
3、GCD 全称:Grand Central Dispatch,简称GCD,iOS4才开始支持,是纯C语言的API。自iPad2开始,苹果设备开始有了双核CPU,为了充分利用这2个核,GCD提供了一些新特性来支持多核并行编程
1.NSThread
一个NSThread实例就代表着一条线程
创建
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
参数说明:
selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。
target :selector消息发送的对象
argument:传输给target的唯一参数,也可以是nil
第一种方式会直接创建线程并且开始运行线程,第二种方式是先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息
例子:
// 初始化线程2 NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"userinfo"] autorelease];3 // 开启线程4 [thread start];
run:方法
- (void)run:(NSString *)string { NSThread *current = [NSThread currentThread]; NSLog(@"执行了run:方法-参数:%@,当前线程:%@", string, current); }//结果执行了run:方法-参数:userinfo,当前线程:<NSThread: 0x889e8d0>{name = (null), num = 3}
同步锁
创建锁可使用
NSLock *theLock = [[NSLock alloc] init];
已上面例子,对run:加锁
- (void)run:(NSString *)string { [theLock lock]; NSThread *current = [NSThread currentThread]; NSLog(@"执行了run:方法-参数:%@,当前线程:%@", string, current); [theLock unlock]; }
还有其他的一些锁对象,比如:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等
2、NSOperation
(1).思路:
1> 先将需要执行的操作封装到一个NSOperation对象中
2> 然后将NSOperation对象添加到NSOperationQueue中
3> 系统会自动将NSOperation中封装的操作放到一条新线程中执行
在此过程中,我们根本不用考虑线程的生命周期、同步、加锁等问题
(2).创建
默认情况下,NSOperation并不具备封装操作的能力,必须使用它的子类,使用NSOperation子类的方式有3种:
1> NSInvocationOperation
2> NSBlockOperation
3> 自定义子类继承NSOperation,实现内部相应的方法
(3).使用
NSInvocationOperation例子:
NSInvocationOperation *operation = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"userinfo"] autorelease]; NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperation:operation];
NSBlockOperation例子:
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){ NSLog(@"执行了一个新的操作");}];NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperation:operation];
若要并发执行多个任务,可使用NSBlockOperation
的addExecutionBlock:
方法添加了新的操作
[operation addExecutionBlock:^() { NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]); }];
自定义NSOperation:
如果NSInvocationOperation和NSBlockOperation不能满足需求,我们可以直接新建子类继承NSOperation,并添加任何需要执行的操作。如果只是简单地自定义NSOperation,只需要重载-(void)main这个方法,在这个方法里面添加需要执行的操作。
注意:如果创建NSOperation后直接使用[operation start];
执行线程还是会在当前线程同步执行操作,并没有异步执行
(4).取消操作
operation开始执行之后, 默认会一直执行操作直到完成,我们也可以调用cancel方法中途取消操作
[operation cancel];
(5).其他
如何控制线程池中的线程数?
队列里可以加入很多个NSOperation, 可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。
通过下面的代码设置:
[queue setMaxConcurrentOperationCount:5];
线程池中的线程数,也就是并发操作数。默认情况下是-1,-1表示没有限制,这样会同时运行队列中的全部的操作。
3.GCD
GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。
一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。
(1).队列
GCD 是异步任务的技术之一,开发者可以用它将自定义的任务(task)追加到适当的派发队列(dispatch queue),就能生成必要的线程并执行任务。
在 GCD 中有三种队列:主队列(main queue)、全局队列(global queue)、用户队列(user-created queue)。
*全局队列是并发队列,即队列中的任务(task)执行顺序和进入队列的顺序无关;
主队列是串行队列,队列中的任务按FIFO(first input first output,先进先出)的顺序执行。
用户队列是用户自己创建的队列,可创建串行的也可以创建并行的
*
队列创建
全局队列(global queue):
// 获取默认优先级的全局并发dispatch queue dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
第一个参数用于指定优先级,分别使用DISPATCH_QUEUE_PRIORITY_HIGH和DISPATCH_QUEUE_PRIORITY_LOW两个常量来获取高和低优先级的两个queue;第二个参数目前未使用到,默认0即可
主队列(main queue):
dispatch_queue_t queue =dispatch_get_main_queue();//获取主线程队列
用户队列(user-created queue):
dispatch_queue_t serialQueue = dispatch_queue_create("cn.itcast.queue", NULL); //串行队列dispatch_queue_t concurrentQueue = dispatch_queue_create("cn.itcast.queue", DISPATCH_QUEUE_CONCURRENT); //并行队列
(2).派发
a.同步派发dispatch_sync
使用例子:
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 耗时的操作 });
同步派发,执行时,会阻塞调用它的线程,然后执行block的内容,执行完成才能继续往下执行。
注意:不用在主线程中,将任务同步派发到主线程队列,会造成死锁。
b.异步派发dispatch_async
使用例子:
dispatch_async(dispatch_get_main_queue(), ^{ // 更新界面 });
异步派发,执行时,不会阻塞调用它的线程,直接执行block内容。
c.其他
dispatch_group_async:可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。
例子:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"group1"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"group2"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:3]; NSLog(@"group3"); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"updateUi"); }); dispatch_release(group);
dispatch_barrier_async:是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行。
void dispatch_barrier_async( dispatch_queue_t queue, dispatch_block_t block);
其中,queue必须是用户通过dispatch_queue_create
创建的并行队列。如:dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT);
(3)总结:
在使用GCD中,派发方式决定了改任务执行时,是否会阻塞调用线程。而执行的队列决定了该任务是串行执行还是并发执行。
- iOS多线程编程总结
- iOS多线程编程概要总结
- ios多线程编程概要 总结
- ios 网络编程总结-多线程
- iOS多线程编程:线程同步总结
- iOS多线程编程:线程同步总结
- IOS多线程编程:线程同步总结
- iOS多线程编程:线程同步总结
- iOS多线程编程:线程同步总结
- iOS多线程编程:线程同步总结
- iOS多线程编程:线程同步总结
- iOS 开发中,多线程编程GCD的常用方法总结
- iOS多线程编程:线程同步总结(NSLock)
- iOS多线程编程——GCD与NSOperation总结
- iOS多线程编程——GCD与NSOperation总结
- iOS多线程编程——GCD与NSOperation总结
- 【iOS沉思录】NSThread、GCD、NSOperation多线程编程总结
- iOS多线程编程——GCD与NSOperation总结
- Android Support兼容包详解
- python处理txt文件
- CGI与fastcgi与php-fpm与php-cgi的关系
- 导航的一些概念
- New Year and Days
- iOS多线程编程总结
- Uva10340
- linux设备驱动归纳总结(十二):简单的数码相框
- Leetcode ☞ 260. Single Number III ☆☆☆
- ceshi
- Leetcode Patching Array
- 效率狗的迷茫!改动一点节约了1分钟
- SDUT 1867 最短路径问题 (Floyd 多源)
- iOS 集成apple Pay 接入详细教程