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的例子(在后台加载图片避免阻塞主线程)
- dispatch_queue_t network_queue;
- network_queue = dispatch_queue_create("com.myapp.network", nill);
- dispatch_async(network_queue, ^{
- UIImage *cellImage = [self loadMyImageFromNetwork:image_url];
- // 将图片cache到本地
- [self cacheImage:cellImage];
- // 回到主线程
- dispatch_async(dispatch_get_main_queue(), ^{
- // 显示图片到界面
- [self displayImageToTableView:cellImage];
- }];
- } );
NSOperation 的例子
这个例子中,我写了一个NSOperation来抓取一个网页的字符串,然后把这些字符串放到NSXMLDocument中解析,然后在此操作完成之前,传递NSXMLDocument对象给主线程。
- PageLoadOperation.h
- #import <Cocoa/Cocoa.h>
- @interface PageLoadOperation : NSOperation {
- NSURL *targetURL;
- }
- @property(retain) NSURL *targetURL;
- - (id)initWithURL:(NSURL*)url;
- @end
- #import "PageLoadOperation.h"
- #import "AppDelegate.h"
- @implementation PageLoadOperation
- @synthesize targetURL;
- - (id)initWithURL:(NSURL*)url;
- {
- if (![super init]) return nil;
- [self setTargetURL:url];
- return self;
- }
- - (void)dealloc {
- [targetURL release], targetURL = nil;
- [super dealloc];
- }
- - (void)main {
- NSString *webpageString = [[[NSString alloc] initWithContentsOfURL:[self targetURL]] autorelease];
- NSError *error = nil;
- NSXMLDocument *document = [[NSXMLDocument alloc] initWithXMLString:webpageString
- options:NSXMLDocumentTidyHTML
- error:&error];
- if (!document) {
- NSLog(@"%s Error loading document (%@): %@", _cmd, [[self targetURL] absoluteString], error);
- return;
- }
- [[AppDelegate shared] performSelectorOnMainThread:@selector(pageLoaded:)
- withObject:document
- waitUntilDone:YES];
- [document release];
- }
- @end
就像你看到的,这个类非常的简单。初始化的时候,它接受了一个URL,并且存储了这个URL。当main方法被调用时,它从URL中构造了一个字符串,然后传递这个字符串传给NSXMLDocument初始化。假如在装载xml文档的时候,没有错误发生,它将回传给AppDelegate,在主线程上,然后此任务完成。当main方法结束时,NSOperation也会在队列中被释放。
- AppDelegate.h
- #import <Cocoa/Cocoa.h>
- @interface AppDelegate : NSObject {
- NSOperationQueue *queue;
- }
- + (id)shared;
- - (void)pageLoaded:(NSXMLDocument*)document;
- @end
- #import "AppDelegate.h"
- #import "PageLoadOperation.h"
- @implementation AppDelegate
- static AppDelegate *shared;
- static NSArray *urlArray;
- - (id)init
- {
- if (shared) {
- [self autorelease];
- return shared;
- }
- if (![super init]) return nil;
- NSMutableArray *array = [[NSMutableArray alloc] init];
- [array addObject:@"http://www.google.com"];
- [array addObject:@"http://www.apple.com"];
- [array addObject:@"http://www.yahoo.com"];
- [array addObject:@"http://www.zarrastudios.com"];
- [array addObject:@"http://www.macosxhints.com"];
- urlArray = array;
- queue = [[NSOperationQueue alloc] init];
- shared = self;
- return self;
- }
- - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
- {
- for (NSString *urlString in urlArray) {
- NSURL *url = [NSURL URLWithString:urlString];
- PageLoadOperation *plo = [[PageLoadOperation alloc] initWithURL:url];
- [queue addOperation:plo];
- [plo release];
- }
- }
- - (void)dealloc
- {
- [queue release], queue = nil;
- [super dealloc];
- }
- + (id)shared;
- {
- if (!shared) {
- [[AppDelegate alloc] init];
- }
- return shared;
- }
- - (void)pageLoaded:(NSXMLDocument*)document;
- {
- NSLog(@"%s Do something with the XMLDocument: %@", _cmd, document);
- }
- @end
在这个例子的AppDelegate中,两件事正在发生。第一,在初始化方法中,NSOperationQueue装载一些URL数组。然后当应用程序完成装载的时候,也就是在被应用程序实例调用的applicationDidFinishLaunching方法中,通过url数组循环,为每个url创建一个任务,然后放置这些任务到NSOperationQueue中。只要任何一个NSOperation被安排到队列中,就回立刻被队列获取,然后分配它到一个NSThread中,然后NSThread就会运行NSOperation中的main函数中的方法。一旦操作完成,线程就报告给队列,然后队列就释放这个操作。
NSOperationQueue同步
在这个简单的例子中,很困那导入足够多的对象,使之并行运行。然而,如果你运行的任务需要花费大量的时间,你将会看到此队列同时运行很多任务。幸运的是,如果你想降低并发任务的数量,你能在AppDelegate的初始化方法中,
如下的设置:
- - (id)init
- {
- if (shared) {
- [self autorelease];
- return shared;
- }
- if (![super init]) return nil;
- NSMutableArray *array = [[NSMutableArray alloc] init];
- [array addObject:@"http://www.google.com"];
- [array addObject:@"http://www.apple.com"];
- [array addObject:@"http://www.yahoo.com"];
- [array addObject:@"http://www.zarrastudios.com"];
- [array addObject:@"http://www.macosxhints.com"];
- urlArray = array;
- queue = [[NSOperationQueue alloc] init];
- [queue setMaxConcurrentOperationCount:2];
- shared = self;
- return self;
- }
- IOS中线程的处理(GCD,NSOperation,NSOperationQueue)
- iOS - 线程(NSThread / NSOperation / GCD)
- NSThread、NSOperation、GCD、NSOperationQueue
- iOS多线程编程 (二)-----NSOperation和NSOperationQueue的使用
- 关于iOS多线程Pthreads, NSThread, GCD, NSOperation & NSOperationQueue
- iOS多线程 NSOperation和NSOperationQueue的使用
- iOS开发-NSOperation和NSOperationQueue的使用
- NSThread、NSOperation/NSOperationQueue、GCD多线程
- ios之多线程-NSThead、GCD、NSOperationQueue
- iOS 之 NSOperation,NSOperationQueue
- iOS 中的线程(1)---①performSelectorInBackground②NSThread③NSOperation 和 NSOperationQueue 的组合
- iOS学习总结之多线程编程NSOperation & NSOperationQueue
- iOS开发中关于多线程的问题(NSOperationQueue,NSThread,GCD)
- 【iOS开发-91】GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例
- iOS线程-NSOperation,NSThread以及GCD
- IOS-线程操作之NSThread/NSOperation/GCD
- iOS之多线程开发(NSThread,NSOperation,GCD)
- iOS开发之多线程NSThread,NSOperation,GCD
- objdump 反汇编文件输出格式
- eclipse failed to create the java virtual machine错误处理
- MPEG4码流格式分析
- PhysX 3.2中的场景查询(2)-过滤
- CareerCup-1.8
- IOS中线程的处理(GCD,NSOperation,NSOperationQueue)
- DispatcherServlet作用(转载)
- 剑指offer面试题21包含Min函数的栈 经典的百度面试题
- TS流解析
- Chapter 2: The Java Programming Environment
- 移动电子商务网站可用性-表单和支付流程
- 高斯消元解方程组 Gauss-Jordan elimination
- hdu2080(夹角有多大II)
- 观察者模式 Go语言实现