一个运行着的程序就是一个进程或者叫做一个任务,一个进程至少包含一个线程,线程就是程序的执行流。Mac和iOS中的程序启动,创建好一个进程的同时, 一个线程便开始运行,这个线程叫主线程。主线程在程序中的地位和其他线程不同,它是其他线程最终的父线程,且所有界面的显示操作即AppKit或 UIKit的操作必须在主线程进行。
系统中的每一个进程都有自己独立的虚拟内存空间,而同一个进程中的多个线程则共用进程的内存空间。每创建一个新的线程,都需要一些内存(如每个线程有自己的Stack空间)和消耗一定的CPU时间。另外当多个线程对同一个资源出现争夺的时候需要注意线程安全问题。
1.NSThread:
1> 优点:NSThread对象建立一个线程非常方便;
2> 缺点:要使用NSThread管理多个线程非常困难,不推荐使用;
3> 技巧:使用[NSThread currentThread]跟踪任务所在线程,适用于这三种技术.
2.NSOperation/NSOperationQueue:
1> 概念1:是使用GCD实现的一套Objective-C的API;
2> 概念2:是面向对象的多线程技术;
3> 优点:提供了一些在GCD中不容易实现的特性,如:限制最大并发数量,操作之间的依赖关系.
3.GCD---Grand Central Dispatch:
1> 概念:是基于C语言的底层API;
2> 优点1:用Block定义任务,使用起来非常灵活便捷;
3> 优点2:提供了更多的控制能力以及操作队列中所不能使用的底层函数.
1、线程创建与启动
线程创建主要有二种方式:
当然,还有一种比较特殊,就是使用所谓的convenient method,这个方法可以直接生成一个线程并启动它,而且无需为线程的清理负责。这个方法的接口是:
前两种方法创建后,需要手机启动,启动的方法是:
eg:
1.1:[NSThread detachNewThreadSelector:@selector(threadInMainMethod:) toTarget:self withObject:nil];
1.2:NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadInMainMethod:) object:nil];
[myThread start];
1.3: [obj performSelectorInBackground:@selector(threadMe) withObject:nil];
[queue setMaxConcurrentOperationCount:1];
设置优先级:setQueuePriority:
设置队列的最大并发数:maxConcurrentOperationCount
取消单个线程: 通过NSOperation的cancel方法
取消全部线程:通过NSOperationQueue的cancelAllOperations
暂停和继续:通过修改NSOperationQueue的suspended属性
五 GCD
GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 耗时的操作
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];
NSData * data = [[NSData alloc]initWithContentsOfURL:url];
UIImage *image = [[UIImage alloc]initWithData:data];
if (data != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
});
}
});
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"group1");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"group2");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"group3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUi");
});
dispatch_release(group);
dispatch_group_async是异步的方法,运行后可以看到打印结果:
2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi
每个一秒打印一个,当第三个任务执行后,upadteUi被打印。
dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
例子代码如下:
2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async
2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3
请注意执行的时间,可以看到执行的顺序如上所述。部分内容参照博客,感谢原作者容芳志 http://blog.csdn.net/totogo2010/article/details/8016129