主线程里面执行耗时操作会导致界面阻塞,所以一般把耗时操作放到子线程执行,例如网络请求、线程睡眠、加载文件、大量运算。
1、不要把耗时操作放到主线程。
2、不要把修改页面的代码放到子线程(子线程修改页面不会等到及时更新)
第一种开启子线程的方法
NSThread
//
开启一个子线程
[
NSThread
detachNewThreadSelector
:
@selector
(createMouse)
toTarget
:
self
withObject
:
nil
];
//
返回主线程
[self performSelectorOnMainThread:@selector(updateUI:)withObject:self.mouse waitUntilDone:NO];
第二种开启子线程的方法
GCD
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,自己创建的线程队列为串行队列,获取系统提供的线程队列为并行队列。
//
开启一个子线程
dispatch_async ( dispatch_get_global_queue ( DISPATCH_QUEUE_PRIORITY_DEFAULT , 0 ), ^{
NSData *data = [ NSData data WithContentsOfURL :[ NSURL URLWithString : self . imagaPaths [indexPath. row ]]];
UIImage *image = [ UIImage image WithData :data];
// 返回主线程
dispatch_async ( dispatch_get_main_queue (), ^{
cell. imageView . image = image;
[cell setNeedsLayout ];
});
dispatch_async ( dispatch_get_global_queue ( DISPATCH_QUEUE_PRIORITY_DEFAULT , 0 ), ^{
NSData *data = [ NSData data WithContentsOfURL :[ NSURL URLWithString : self . imagaPaths [indexPath. row ]]];
UIImage *image = [ UIImage image WithData :data];
// 返回主线程
dispatch_async ( dispatch_get_main_queue (), ^{
cell. imageView . image = image;
[cell setNeedsLayout ];
});
});
第三种开启子线程的方法
NSOperation
创建出来的线程队列默认为并行队列。
- (void)viewDidLoad
{
[super viewDidLoad];
//方式一开启一个线程
NSOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(newThreadAction)object:nil];
//方式二开启一个线程
NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i=0; i<5; i++) {
[NSThread sleepForTimeInterval:.5];
NSLog(@"线程2--%d",i);
}
}];
//创建线程队列,默认创建出来的线程队列为并行队列
NSOperationQueue *myQueue = [[NSOperationQueue alloc]init];
//设置最大同时执行的线程数量
[myQueue setMaxConcurrentOperationCount:1];
//给op1添加一个依赖依赖op2
[op1 addDependency:op2];
//将线程添加到队列,线程添加到队列后才会执行
[myQueue addOperation:op1];
[myQueue addOperation:op2];
}
- (void)newThreadAction{
for (int i=0; i<5; i++) {
[NSThread sleepForTimeInterval:.5];
NSLog(@"线程1--%d",i);
}
{
[super viewDidLoad];
//方式一开启一个线程
NSOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(newThreadAction)object:nil];
//方式二开启一个线程
NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i=0; i<5; i++) {
[NSThread sleepForTimeInterval:.5];
NSLog(@"线程2--%d",i);
}
}];
//创建线程队列,默认创建出来的线程队列为并行队列
NSOperationQueue *myQueue = [[NSOperationQueue alloc]init];
//设置最大同时执行的线程数量
[myQueue setMaxConcurrentOperationCount:1];
//给op1添加一个依赖依赖op2
[op1 addDependency:op2];
//将线程添加到队列,线程添加到队列后才会执行
[myQueue addOperation:op1];
[myQueue addOperation:op2];
}
- (void)newThreadAction{
for (int i=0; i<5; i++) {
[NSThread sleepForTimeInterval:.5];
NSLog(@"线程1--%d",i);
}
}
GCD与NSOperation的区别
1、GCD,代码更简洁,使用更加方便,GCD更加高效,因为属于C语言的语法,更底层。
2、NSOperation,灵活控制线程之间的关系,可以设置同时执行的线程数量。
//
设置最大同时执行的线程数量,如果设置为1,则相当于线程串行执行
[myQueue setMaxConcurrentOperationCount:1];
//
给
op1
添加一个依赖
依赖
op2,先执行op2,再执行op1
[op1 addDependency:op2];