您的位置:首页 > 移动开发 > IOS开发

iOS使用多线程提高数据并发访问 之四

2013-07-30 10:22 344 查看
现在,我将会向你更深入的介绍如何使用之前提到的方法来创建新的operations。

NSInvocationOperation

当一个新的NSInvocationOperation对象创建时,它是用来运行指定的一个方法。你可能会想要使用这个对象,如果
在你的应用中你想避免创建过多的自定义operation类。

你正在添加或维护一个已经存在的应用,而它的类都已经定义好了,同时你不想修改NSOperation的子类。

selector能够根据用户的输入进行改变。在这种情况下,你只需要用一个已经选择好的selector创建一个新的NSInvocationOperation对象。

创建一个NSInvocationOperation对象的代码如下:

NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:) object:data];

这个和使用NSThread创建和detach一个新的线程类似。你传递一个目标对象,你想要调用的selector,还有在执行时selector想要使用的参数。

NSBlockOperation

NSBlockOperation是NSOperation的另一个子类。当你创建一个block operation时,你必须在这个operation 对象内至少添加一个block。之后你可以在这个operation对象内添加更多的block来执行。当operation queue执行这个block operation时,它会在这个block operation结束之前执行这个block operation内的所有blocks。因此,你可以使用这个operation对象来跟踪一组blocks,然后你可以合并会处理相关结果。

创建一个block operation对象,你可以使用下面的代码:

NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
NSLog(@"Beginning operation.\n");
// Do some work.
}];

然后你可以在这个operation中添加另一个block:

[theOp addExecutionBlock:[NSBlockOperation blockOperationWithBlock: ^{
NSLog(@"Beginning operation.\n");
// Do some work.
}];

NSOperation

NSOperation是用来被继承的一个类。要继承NSOperation,你可以使用两种推荐的方法来创建。
自定义初始化方法:可以在这个类中接收数据和进行一些必要的逻辑处理。例如,你可以在init方法中接收一个url来下载图片,类似这样:

- (id)initWithData:(id)data {
if ((self = [super init]))
myData = data;
return self;
}

main方法:这是一个必须的方法,当任务启动时被调用。

为了得到一个并发的NSOperation子类,你必须重写更多的方法来帮助NSOperationQueue对象来处理调用者的多线程请求。
start或main:你需要重写这个方法或main方法,当线程启动你的operations时,能够执行你的逻辑。默认,这个方法没有做任何事情,除了调用main方法。因此,你可以重写这个方法或main方法。

isExecuting或isFinished:你的operation需要报告它当前的状态给外面的客户端。有两个最重要的状态就是:你的operation已经开始执行,你的operation已经执行完毕。因此你需要在这里通过使用属性或实例变量来跟踪和报告这些状态。

isConcurrent:你必须重写这个方法,然后返回YES。

其他方法不是强制性的,但是你可能经常会需要他们。

其他逻辑处理方法:除非你想把所有的代码都放在main方法中,你同样需要其他的方法来包含你的逻辑处理代码。

Listing 6-4 显示了一个自定义和并发的NSOperation类的完整代码。







Listing 6-4 展示了如何编写一个自定义的NSOperation,使用多线程来从网络下载一张图片。

注意:如果你之前做过java编程,你会发现NSOperation和Thread类或Runnable接口很像。在Thread类中,你可以继承Thread类,然后重写run方法。对于Runnable接口也一样,你需要实现Runnable接口,然后重写run方法。你可以看到,NSoperation的main方法和Thread类,Runnable接口的run方法是一样的。

配置一个线程

你可以使用一些选项来配置你的线程,这样你就可以使用系统资源而不需要重载他们,尤其是在受限的运行时环境中,比如iPhone。
栈的大小:无论何时创建一个线程,OS会给线程的栈分配一个默认大小的内存来执行。如果你不知道栈是什么,你可以查看第5章。线程内部的栈会保存局部变量和线程执行时的方法。为了设置线程的栈大小,你需要在detaching线程之前设置。对于NSThread,这意味着你要使用初始化方法:

NSThread* myThread = [[NSThread alloc]initWithTarget:self
selector:@selector(myThreadMainMethod:)object:nil];
[myThread setStackSize:40960]; // 40KB here, the size is in bytes and multiple of 4KB
[myThread start]; // Actually create the thread

线程局部存储:没一个线程都有一个键值对的字典来存储数据,它能够在线程内部的任何地方访问。你可以使用这个字典来存储数据,还可以垮线程来呈现数据,而不需要在代码中创建全局变量。你可以使用[aThread threadDictionary]来调用字典。

线程优先级:线程优先级就是OS选择哪个线程来执行的可能性。优先级越高,线程运行的可能性就越大。但是,优先级并不能向你保证任何事情,在OS切换到其他线程之前。它同样不能保证一个高优先级的线程总是被选中,相对于低优先级的线程来说。

本文出自 “移动开发” 博客,请务必保留此出处http://ikinglai.blog.51cto.com/6220785/1260231
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: