iOS中有4中多线程操作方式,分别是:NSObject多线程技术 、NSThread的多线程技术 、 NSOperation,面向对象的多线程技术 、 GCD,C语言实现的多线程技术。接下分别总结这几种方式的用法
一、 NSObject多线程技术
因为iOS中的所有类都是NSObjcet的子类,所以任何类都能够进行如下操作:
使用performSelectorInBackground可以开启后台线程,执行selector选择器选择的方法
使用performSelectorOnMainThread可以重新回到主线程执行任务,通常用于后台线程更新界面UI时使用
3> [NSThread sleepForTimeInterval:1.0f];
让当前线程休眠,通常在程序开发中,用于模拟耗时操作,以便跟踪不同的并发执行情况!
提示:使用performSelectorInBackground也可以直接修改UI,但是一定要在主线程中修改UI。
注意:在使用NSThread或者NSObject的线程方法时,一定要使用自动释放池,否则容易出现内存泄露。
实例代码:
UITextField *field = [[UITextField alloc] init];
field.text = @"Programing is fun";
NSLog(@"执行前:%@", [NSThread currentThread]);
[self performSelectorInBackground:@selector(threadTest1) withObject:nil];
//必须调用对象本身实现了的方法
[field performSelectorInBackground:@selector(setPlaceholder:) withObject:@"线程"];
- (void)threadTest1
{
@autoreleasepool {
NSLog(@"执行后:%@", [NSThread currentThread]);
}
}
二、
NSThread的多线程技术
1> 类方法创建线程后直接启动
detachNewThreadSelector
2> 成员方法,在实例化线程对象之后,调用start方法启动线程
initWithTarget
对于NSThread的简单使用,可以用NSObject的performSelectorInBackground替代
同时,在NSThread调用的方法中,同样要使用autoreleasepool进行内存管理,否则容易出现内存泄露。
代码实例:
<pre name="code" class="objc">//新建一个后台线程,调用目标的@selector方法
[NSThread detachNewThreadSelector:@selector(threadTest1) toTarget:self withObject:nil];
//成员方法
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadTest1) object:nil];
//启动线程
[thread start];
- (void)threadTest1
{
@autoreleasepool {
NSLog(@"执行后:%@", [NSThread currentThread]);
}
}
NSOperation,面向对象的多线程技术
1> 使用步骤:
) 实例化操作
a) NSInvocationOperation
b) NSBlockOperation
) 将操作添加到队列NSOperationQueue即可启动多线程执行
2> 更新UI使用主线程队列
[NSOpeationQueue mainQueue] addOperation ^{};
操作队列的setMaxConcurrentOperationCount
可以设置同时并发的线程数量!
提示:此功能仅有NSOperation有!
4> 使用addDependency可以设置任务的执行先后顺序,同时可以跨操作队列指定依赖关系
提示:在指定依赖关系时,注意不要循环依赖,否则不工作。
代码实例:
<pre name="code" class="objc">NSOperationQueue *mainQueue = [[NSOperationQueue alloc] init];
通过使用 NSOperationQueue 可以实现线程的顺序运行,代码如下:
//设置最大线程数量
[mainQueue setMaxConcurrentOperationCount:10];
//下载
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在下载 %@", [NSThread currentThread]);
}];
//滤镜
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"滤镜 %@", [NSThread currentThread]);
}];
//显示
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"更新UI %@", [NSThread currentThread]);
}];
//添加操作之间的依赖关系,即一个执行完以后,另一个才能执行
//依赖关系可以跨线程队列
[op2 addDependency:op1];
[op3 addDependency:op2];
[mainQueue addOperation:op1];
[mainQueue addOperation:op2];
[[NSOperationQueue mainQueue] addOperation:op3];
//下载
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在下载 %@", [NSThread currentThread]);
}];
//滤镜
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"滤镜 %@", [NSThread currentThread]);
}];
//显示
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"更新UI %@", [NSThread currentThread]);
}];
//添加操作之间的依赖关系,即一个执行完以后,另一个才能执行
//依赖关系可以跨线程队列
[op2 addDependency:op1];
[op3 addDependency:op2];
[_mainQueue addOperation:op1];
[_mainQueue addOperation:op2];
[[NSOperationQueue mainQueue] addOperation:op3];
GCD,C语言
GCD就是为了在“多核”上使用多线程技术
要使用GCD,所有的方法都是dispatch开头的
名词解释
全局
队列
异步
同步
3> 要执行异步的任务,就在全局队列中执行即可
异步执行控制不住先后顺序
关于GCD的队列
全局队列
参数:优先级
始终是
串行队列
主队列
5> 异步和同步于方法名无关,与运行所在的队列有关!
6> dispatch_sync(queue, ^{
NSLog(@"a -> %@", [NSThread currentThread]);
});
无论是什么队列都是在主线程中运行
同步主要用来控制方法的被调用的顺序
并行代码如下:
//1.队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//2.将任务异步执行 无法控制先后顺序
dispatch_async(queue, ^{
NSLog(@"a -> %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"b - > %@", [NSThread currentThread]);
});
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"main -> %@", [NSThread currentThread]);
});
串行代码如下:
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"a -> %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"b - > %@", [NSThread currentThread]);
});