ios多线程编程(一)
ios多线程编程:
本文的大部分整合参考博客http://blog.csdn.net/q199109106q/article/details/8566300的多线程篇章,加上自己的理解
1.多线程编程之NSOperationQueue(一)
[iOS]后台工作队列:NSOperationQueue、NSOperation、NSInvocationOperation
NSOperationQueue里面可以添加多个Operation,我们可以设置这个队里每次被处理的操作数量。
NSOperationQueue *aQ = [[NSOperationQueue alloc] init]; [aQ setMaxConcurrentOperationCount:10];
这里的setMaxConcurrentOperationCount就是同时被处理的“操作数”,参数为整数int或NSInteger
NSInvocationOperation *aOpt = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil]; - (void)doSomeThing { //读取大量大延迟数据等等 //可以使用performSelectorOnMainThread来将得来的数据返回到主线程 }
在doSomeThing函数里面,我可以从网上读取一些东西,但是读取是需要占用时间,而堵塞主线程的。而使用NSOperation这样使用就不会了。
2.多线程编程之NSOperationQueue(二)
多线程编程是防止主线程堵塞,增加运行效率等等的最佳方法。而原始的多线程方法存在很多的毛病,包括线程锁死等。在Cocoa中,Apple提供了NSOperation这个类,提供了一个优秀的多线程编程方法。
具体步骤:
想要讲一个线程里的公众单独成类,可以继承NSOperation
@interface ImageLoadingOperation : NSOperation { NSURL *imageURL; //这个例子里面需要传入一个图片地址,所以定义一个NSURL变量 id target; //由于需要返回一些值,所以需要一个对象参数返回要被返回的对象(运行此线程的类对象) SEL action; //返回值要激发的方法函数 }
初始化函数,传入设置参数
(id)initWithImageURL:(NSURL *)theImageURL target:(id)theTarget action:(SEL)theAction { self = [super init]; //在老帖里面解释过为什么需要这么做了 if (self) { imageURL = [theImageURL retain]; // 拷贝进对象,并retain(为什么?请查老帖) target = theTarget; action = theAction; } return self; }
实例化Operation,加入到Queue中
// 这些是需要对其初始化的类中的代码 ImageLoadingOperation *operation = [[ImageLoadingOperation alloc] initWithImageURL:url target:self action:@selector(didFinishLoadingImageWithResult:)]; //初始化 [operationQueue addOperation:operation]; //添加到运行队列 [operation release]; //由于队列对其retain,所以我们需要release它
一个NSOperationQueue 操作队列,就相当于一个线程管理器,而非一个线程。因为你可以设置这个线程管理器内可以并行运行的的线程数量等等。
一个NSOperation对象可以通过调用start方法来执行任务,默认是同步执行的。也可以将NSOperation添加到一个NSOperationQueue(操作队列)中去执行,而且是异步执行的。
3.多线程编程之NSOperationQueue总结
关于添加NSOperation到NSOperationQueue中
1)添加一个operation
[queue addOperation:operation];2)添加一组operation [queue addOperations:operations waitUntilFinished:NO];
3)添加一个block形式的operation
[queue addOperationWithBlock:^() {
NSLog(@"执行一个新的操作,线程:%@", [NSThread currentThread]); }];NSOperation添加到queue之后,通常短时间内就会得到运行。但是如果存在依赖,或者整个queue被暂停等原因,也可能需要等待。
注意:NSOperation添加到queue之后,绝对不要再修改NSOperation对象的状态。因为NSOperation对象可能会在任何时候运行,因此改变NSOperation对象的依赖或数据会产生不利的影响。你只能查看NSOperation对象的状态, 比如是否正在运行、等待运行、已经完成等
添加NSOperation的依赖对象
1.当某个NSOperation对象依赖于其它NSOperation 对象的完成时,就可以通过addDependency方法添加一个或者多个依赖的对象,只有所有依赖的对象都已经完成操作,当前NSOperation对 象才会开始执行操作。另外,通过removeDependency方法来删除依赖对象。[operation2 addDependency:operation1]; 依赖关系不局限于相同queue中的NSOperation对象,NSOperation对象会管理自己的依赖, 因此完全可以在不同的queue之间的NSOperation对象创建依赖关系
注意不能建议环形依赖,不然会造成死锁。
2.依赖关系会影响到NSOperation对象在queue中的执行顺序。
没有依赖关系时,默认是按照添加顺序执行的。
设置了依赖关系,则依赖先执行。
Operation的具体执行顺序:
对于添加到queue中的operations,它们的执行顺序取决于2点:
1.首先看看NSOperation是否已经准备好:是否准备好由对象的依赖关系确定
2.然后再根据所有NSOperation的相对优先级来确定。优 先级等级则是operation对象本身的一个属性。默认所有operation都拥有“普通”优先级,不过可以通过setQueuePriority: 方法来提升或降低operation对象的优先级。优先级只能应用于相同queue中的operations。如果应用有多个operation queue,每个queue的优先级等级是互相独立的。因此不同queue中的低优先级操作仍然可能比高优先级操作更早执行。