多线程的种类:
1,脱离线程:线程结束后被销毁。
2,非脱离线程:线程结束后被挂起,等待再次调用。(例如:iOS系统等待来电的进程)。
iOS 中实现多线程的种类:
1,NSObject
2,NSThread
3,NSOperation / NSOperationQueue
4,GCD
iOS在“栈区”按4k对齐的方式默认为主线程分配 1MB 的空间,为其他子线程分配 512KB 的空间,分配的空间用来存放线程中的变量,一般情况下足够使用了。
iOS中,主线程与子线程共用堆空间。
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
在程序的入口(main函数)中,存在一个自动释放池,它可以自动释放由主线程负责执行的代码,子线程开辟的空间不在主线程的管辖范围之内(线程间互不干扰),所以若不释放子线程开辟的空间,会造成内存管理的错误。可能因为内存占用过大,导致程序crash。所以在子线程调用的方法中要加入@autoreleasepool{}来释放收到autorelease消息的对象。
首先在下面写一个方法方便测试调用:
- (void)task:(id)sender{
@autoreleasepool{
NSLog(@"%@",sender);
}
}
NSObject 多线程方法:
[self performSelectorInBackground:@selector(task:) withObject:@"参数"];
//self指某类的静态对象
//参数可以是任意类型
//运行结果:控制台打印“参数”;
NSThread 多线程方法:
方式一:
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(task:) object:@"参数"];
[thread1 start];//需要手动开始执行子线程
//运行结果:控制台打印“参数”
方式二:
[NSThread detachNewThreadSelector:@selector:(task:) toTarget:self withObject:@"参数"];
//运行结果:控制台打印“参数”
NSOperation 多线程方法:
方式一: NSInvocationOperation
NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task:) object:@"参数"];
[invocation start];//需要手动开启
//运行结果:控制台打印“参数”
方式二:NSBlockOperation
__weak typeof(self) tempSelf = self;
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
[tempSelf task:@"参数"];
}];
[block start];//需要手动开始
//运行结果:控制台打印“参数”;
方式三:NSOperationQueue
可以通过NSOperationQueue创建队列,向队列中添加操作。
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *invo = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector:(task:) object:@"参数1"];
__weak typeof(self) temp = self;
//block会持有内部变量,为了防止block持有self造成循环持有,要用__weak typeof()来定义一个新的变量。
NSBlockOperation *blo = [NSBlockOperation blockOperationWithBlock:^{
[temp task:@"参数2"];
}];
[queue setMaxConcurrentOperationCount:2];
//一定要提前设置好并发数
[queue addOperation:blo];
[queue addOperation:invo];
//运行结果:控制台打印“参数1”“参数2” 或者 “参数2”“参数1”
可以在方法中打印[NSThread isMainThread]的值来判断是否为主线程。上述返回值类型为:BOOL