NSOperationQueue
1,operationQueue 里邊應該可以同時添加多個operation吧?
是的,本來operationQueue的目的就是多線程管理,那多線程,可不只是一個線程。
而且我們可以設置這個隊列每次被處理的“操作”數量
NSOperationQueue *aQ = [[NSOperationQueue alloc] init];
[aQ setMaxConcurrentOperationCount:10];
這里的setMaxConcurrentOperationCount就是同時被處理的“操作數”,參數為整數int或NSInteger (兩個是一樣的,不記得的可以在我的博客里面搜索一下噢~)
2,那main函數應該怎么寫?
main函數中其實只需要寫你要在另外一個進程里面作的事情。比如對于我來說,我常常只是作一個簡單的事情,那我會用NSInvocationOperation,NSOperation的簡化版。比如說:
NSInvocationOperation *aOpt = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(doSomeThing) object:nil];
- (void)doSomeThing
{
//讀取大量大延遲數據等等
//可以使用performSelectorOnMainThread來將得來的數據返回到主線程
}
在doSomeThing函數里面,我可以從網上讀取一些東西,但是讀取是需要占用時間,而堵塞主線程的。而使用NSOperation這樣使用就不會了。
而如果是NSOperation,雖然復雜了一些,又是做一個NSOperation的子類。其實main函數做得事情和doSomeThing是一抹一樣的。只不過如果你制作這個子類,你對其操作的內容可以更多,可以制作更復雜的讀取,載入操作等等,而且你可以重復使用這個類功能阿。再者,NSOperation也提供了對runtime操作的支持,不過那就太麻煩了,一般不大用的上。
NSOperation
多線程編程是防止主線程堵塞,增加運行效率等等的最佳方法。而原始的多線程方法存在很多的毛病,包括線程鎖死等。在Cocoa中,Apple提供了NSOperation這個類,提供了一個優秀的多線程編程方法。
本次講解NSOperation的使用方法:
1,將想在另外一個線程的工作單獨成類,并設置其父類為NSOperation:
@interface ImageLoadingOperation : NSOperation {
NSURL *imageURL; //這個例子里面需要傳入一個圖片地址,所以定義一個NSURL變量
id target; //由于需要返回一些值,所以需要一個對象參數返回要被返回的對象(運行此線程的類對象)
SEL action; //返回值要激發的方法函數
}
2,借由其初始化方法來傳入所需要的參數和對象
- (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;
}
呼叫這個類對象的時候,傳入所需要的參數和對象
// 這些是需要對其初始化的類中的代碼
ImageLoadingOperation *operation = [[ImageLoadingOperation alloc] initWithImageURL:url target:self action:@selector(didFinishLoadingImageWithResult:)]; ?//初始化
[operationQueue addOperation:operation]; //添加到運行隊列
[operation release]; ?//由于隊列對其retain,所以我們需要release它
3,在我們的線程操作類中的main函數執行所需要的工作
- (void)main
{
// 同時載入圖片
NSData *data = [[NSData alloc] initWithContentsOfURL:imageURL];
UIImage *image = [[UIImage alloc] initWithData:data];
// 打包返回給初始類對象,然后執行其指定的操作
NSDictionary *result = [NSDictionary dictionaryWithObjectsAndKeys:image, ImageResultKey, imageURL, URLResultKey, nil];
[target performSelectorOnMainThread:action withObject:result waitUntilDone:NO];
[data release]; //不需要了就清理
[image release];
}
這些就是一個簡單的NSOperation的使用過程了。其實看看嘛,非常簡單的,正如蘋果為我們準備的其他API一樣!
NSInvocationOperation
多線程編程是防止主線程堵塞,增加運行效率等等的最佳方法。而原始的多線程方法存在很多的毛病,包括線程鎖死等。在Cocoa中,Apple提供了NSOperation這個類,提供了一個優秀的多線程編程方法。
本次介紹NSOperation的子集,簡易方法的NSInvocationOperation:
@implementation MyCustomClass
- (void)launchTaskWithData:(id)data
{
//創建一個NSInvocationOperation對象,并初始化到方法
//在這里,selector參數后的值是你想在另外一個線程中運行的方法(函數,Method)
//在這里,object后的值是想傳遞給前面方法的數據
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:) object:data];
// 下面將我們建立的操作“Operation”加入到本地程序的共享隊列中(加入后方法就會立刻被執行)
// 更多的時候是由我們自己建立“操作”隊列
[[MyAppDelegate sharedOperationQueue] addOperation:theOp];
}
// 這個是真正運行在另外一個線程的“方法”
- (void)myTaskMethod:(id)data
{
// Perform the task.
}
@end
一個NSOperationQueue 操作隊列,就相當于一個線程管理器,而非一個線程。因為你可以設置這個線程管理器內可以并行運行的的線程數量等等。下面是建立并初始化一個操作隊列:
@interface MyViewController : UIViewController {
NSOperationQueue *operationQueue;
//在頭文件中聲明該隊列
}
@end
@implementation MyViewController
- (id)init
{
self = [super init];
if (self) {
operationQueue = [[NSOperationQueue alloc] init]; //初始化操作隊列
[operationQueue setMaxConcurrentOperationCount:1];
//在這里限定了該隊列只同時運行一個線程
//這個隊列已經可以使用了
}
return self;
}
- (void)dealloc
{
[operationQueue release];
//正如Alan經常說的,我們是程序的好公民,需要釋放內存!
[super dealloc];
}