IOS中线程的处理(GCD,NSOperation,NSOperationQueue)

来源:互联网 发布:win10 v1703新手优化 编辑:程序博客网 时间:2024/06/06 06:30

GCD是一种轻量级的方法来代表将要被并发执行的任务单位。你并不需要去计划这些任务单位;系统会为你做计划。在块(block)中添加依赖会是一件令人头疼的事情。取消或者暂停一个块会给一个开发者产生额外的工作!

NSOperation和NSOperationQueue对比GCD会带来一点额外的系统开销,但是你可以在多个操作(operation)中添加附属。你可以重用操作,取消或者暂停他们。NSOperation和 Key-Value Observation (KVO)是兼容的;例如,你可以通过监听NSNotificationCenter去让一个操作开始执行。

//使用GCD的模板

1.dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

2.    // switch to a background thread and perform your expensive operation

3.

4.    dispatch_async(dispatch_get_main_queue(), ^{

5.        // switch back to the main thread to update your UI

6.

7.    });

8.});

//使用GCD的例子(在后台加载图片避免阻塞主线程)

 

  1. dispatch_queue_t network_queue;    
  2. network_queue = dispatch_queue_create("com.myapp.network", nill);    
  1. dispatch_async(network_queue, ^{      
  2.     UIImage *cellImage = [self loadMyImageFromNetwork:image_url];      
  3.     // 将图片cache到本地       
  4.     [self cacheImage:cellImage];      
  5.    // 回到主线程       
  6.    dispatch_async(dispatch_get_main_queue(), ^{      
  7.       // 显示图片到界面       
  8.       [self displayImageToTableView:cellImage];      
  9.    }];        
  10. } );    

 

 

 

 

NSOperation 的例子

    这个例子中,我写了一个NSOperation来抓取一个网页的字符串,然后把这些字符串放到NSXMLDocument中解析,然后在此操作完成之前,传递NSXMLDocument对象给主线程。

 

[plain] view plaincopy
  1. PageLoadOperation.h  
  2.   
  3. #import <Cocoa/Cocoa.h>  
  4.    
  5.    
  6. @interface PageLoadOperation : NSOperation {  
  7.     NSURL *targetURL;  
  8. }  
  9.    
  10. @property(retain) NSURL *targetURL;  
  11.    
  12. - (id)initWithURL:(NSURL*)url;  
  13.    
  14. @end   

 

[plain] view plaincopy
  1. #import "PageLoadOperation.h"  
  2. #import "AppDelegate.h"  
  3.    
  4. @implementation PageLoadOperation  
  5.    
  6. @synthesize targetURL;  
  7.    
  8. - (id)initWithURL:(NSURL*)url;  
  9. {  
  10.     if (![super init]) return nil;  
  11.     [self setTargetURL:url];  
  12.     return self;  
  13. }  
  14.    
  15. - (void)dealloc {  
  16.     [targetURL release], targetURL = nil;  
  17.     [super dealloc];  
  18. }  
  19.    
  20. - (void)main {  
  21.     NSString *webpageString = [[[NSString alloc] initWithContentsOfURL:[self targetURL]] autorelease];  
  22.    
  23.     NSError *error = nil;  
  24.     NSXMLDocument *document = [[NSXMLDocument alloc] initWithXMLString:webpageString   
  25.                                                               options:NSXMLDocumentTidyHTML   
  26.                                                                 error:&error];  
  27.     if (!document) {  
  28.         NSLog(@"%s Error loading document (%@): %@", _cmd, [[self targetURL] absoluteString], error);  
  29.         return;  
  30.     }     
  31.    
  32.     [[AppDelegate shared] performSelectorOnMainThread:@selector(pageLoaded:)  
  33.                                            withObject:document  
  34.                                         waitUntilDone:YES];  
  35.     [document release];  
  36. }  
  37.    
  38. @end  

 

    就像你看到的,这个类非常的简单。初始化的时候,它接受了一个URL,并且存储了这个URL。当main方法被调用时,它从URL中构造了一个字符串,然后传递这个字符串传给NSXMLDocument初始化。假如在装载xml文档的时候,没有错误发生,它将回传给AppDelegate,在主线程上,然后此任务完成。当main方法结束时,NSOperation也会在队列中被释放。

 

[plain] view plaincopy
  1. AppDelegate.h  

 

[plain] view plaincopy
  1. #import <Cocoa/Cocoa.h>  
  2.    
  3. @interface AppDelegate : NSObject {  
  4.     NSOperationQueue *queue;  
  5. }  
  6.    
  7. + (id)shared;  
  8. - (void)pageLoaded:(NSXMLDocument*)document;  
  9.    
  10. @end  

 

[plain] view plaincopy
  1. #import "AppDelegate.h"  
  2. #import "PageLoadOperation.h"  
  3.    
  4. @implementation AppDelegate  
  5. static AppDelegate *shared;  
  6. static NSArray *urlArray;  
  7.    
  8. - (id)init  
  9. {  
  10.     if (shared) {  
  11.         [self autorelease];  
  12.         return shared;  
  13.     }  
  14.     if (![super init]) return nil;  
  15.    
  16.     NSMutableArray *array = [[NSMutableArray alloc] init];  
  17.     [array addObject:@"http://www.google.com"];  
  18.     [array addObject:@"http://www.apple.com"];  
  19.     [array addObject:@"http://www.yahoo.com"];  
  20.     [array addObject:@"http://www.zarrastudios.com"];  
  21.     [array addObject:@"http://www.macosxhints.com"];  
  22.     urlArray = array;  
  23.    
  24.     queue = [[NSOperationQueue alloc] init];  
  25.     shared = self;  
  26.     return self;  
  27. }  
  28.    
  29. - (void)applicationDidFinishLaunching:(NSNotification *)aNotification  
  30. {  
  31.     for (NSString *urlString in urlArray) {  
  32.         NSURL *url = [NSURL URLWithString:urlString];  
  33.         PageLoadOperation *plo = [[PageLoadOperation alloc] initWithURL:url];  
  34.         [queue addOperation:plo];  
  35.         [plo release];  
  36.     }  
  37. }  
  38.    
  39. - (void)dealloc  
  40. {  
  41.     [queue release], queue = nil;  
  42.     [super dealloc];  
  43. }  
  44.    
  45. + (id)shared;  
  46. {  
  47.     if (!shared) {  
  48.         [[AppDelegate alloc] init];  
  49.     }  
  50.     return shared;  
  51. }  
  52.    
  53. - (void)pageLoaded:(NSXMLDocument*)document;  
  54. {  
  55.     NSLog(@"%s Do something with the XMLDocument: %@", _cmd, document);  
  56. }  
  57.    
  58. @end  

 

    在这个例子的AppDelegate中,两件事正在发生。第一,在初始化方法中,NSOperationQueue装载一些URL数组。然后当应用程序完成装载的时候,也就是在被应用程序实例调用的applicationDidFinishLaunching方法中,通过url数组循环,为每个url创建一个任务,然后放置这些任务到NSOperationQueue中。只要任何一个NSOperation被安排到队列中,就回立刻被队列获取,然后分配它到一个NSThread中,然后NSThread就会运行NSOperation中的main函数中的方法。一旦操作完成,线程就报告给队列,然后队列就释放这个操作。

   NSOperationQueue同步

   在这个简单的例子中,很困那导入足够多的对象,使之并行运行。然而,如果你运行的任务需要花费大量的时间,你将会看到此队列同时运行很多任务。幸运的是,如果你想降低并发任务的数量,你能在AppDelegate的初始化方法中,
如下的设置:

 

[plain] view plaincopy
  1.    
  2. - (id)init  
  3. {  
  4.     if (shared) {  
  5.         [self autorelease];  
  6.         return shared;  
  7.     }  
  8.     if (![super init]) return nil;  
  9.    
  10.     NSMutableArray *array = [[NSMutableArray alloc] init];  
  11.     [array addObject:@"http://www.google.com"];  
  12.     [array addObject:@"http://www.apple.com"];  
  13.     [array addObject:@"http://www.yahoo.com"];  
  14.     [array addObject:@"http://www.zarrastudios.com"];  
  15.     [array addObject:@"http://www.macosxhints.com"];  
  16.     urlArray = array;  
  17.     queue = [[NSOperationQueue alloc] init];  
  18.     [queue setMaxConcurrentOperationCount:2];  
  19.     shared = self;  
  20.     return self;  
  21. }   

 

原创粉丝点击