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中的低优先级操作仍然可能比高优先级操作更早执行。

注意:优先级不能替代依赖关系,优先级只是对已经准备好的 operations确定执行顺序。先满足依赖关系,然后再根据优先级从所有准备好的操作中选择优先级最高的那个执行。

ios

相关推荐