iOS 多线程NSThread、NSOperation、GCD

1,NSThread

1.1初始化

NSThread *thread = [[NSThread alloc]initWithTarget:(id) selector:(SEL) object:(id)];
或者

[NSThread detachNewThreadSelector:(SEL) toTarget:(id) withObject:(id)];
selector:这个线程做什么任务(调哪个方法)

Target:谁来执行这个SEL方法

object:selector方法的传入参数,最多1个,可以传nil

注意:1、上面2个初始化方法的不同,init方法,需要通过 [线程名 start] ,线程才会开始执行。而detach方法,一旦初始化完成,自动执行。

   2、selector方法的内部,需要用@autoreleasepool包起来,防止内存泄露

   3、线程执行完,需要更新UI,一定要在主线程上更新

    @autoreleasepool {
        
        // xxxxxx;

        // 在主线程上更新UI,SEL是更新UI的方法,id是SEL的参数,BOOL是YES表示执行完下面这句才会执行语句A
        [需要更新UI的控件 performSelectorOnMainThread:@selector(SEL) withObject:(id) waitUntilDone:BOOL];                                语句A;
    }


1.2NSThread的优缺点:

优点:简单

缺点:不能控制线程最大数量,不能控制线程的执行顺序


2.NSOperation之NSInvocation

NSOpeation的子类:NSInvocation、NSBlockOperation,只能使用子类。

类似CAAnimation,只能使用CAAnimation子类CABasicAnimation、CAKeyFrameAnimation、CATransition。

2.1初始化

NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:(id) selector:(SEL) object:(id)];

selector:这个线程做什么任务(调哪个方法)

Target:谁来执行这个SEL方法

object:selector方法的传入参数,最多1个,可以传nil

2.2执行线程(在主线程上)

<span style="font-family: Arial, Helvetica, sans-serif;">[op start]; // 通过start方法,线程是直接在主队列运行</span>

2.3执行线程(在新线程上)

如果要开启新的线程,需要使用NSOperationQueue来管理线程,NSOperationQueue通常是属性

@property (strong, nonatomic) NSOperationQueue *queue;
[self.queue addOperation:op]; // op一旦添加到队列,就自动开启新线程

2.4设置线程的最大并发数量

[self.queue setMaxConcurrentOperationCount:4];

2.5设置多个线程之间的依赖关系

// 下载图片
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:(downloadImage) object:nil];
// 处理图片
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:(handleImage) object:nil];
// 显示图片
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:(showImage) object:nil];
// 设置依赖关系
[op2 addDependency:op1];
[op3 addDependency:op2];
// 添加线程到队列
[self.queue addOperation:op3];
[self.queue addOperation:op2];
[self.queue addOperation:op1];

3.NSOperation之NSBlockOperation

3.1初始化

        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            // 这里添加该线程需要做的任务
        }];
        [self.queue addOperation:op]; 

3.3在NSInvocationOperation的基础上,补充更新UI界面,同样适用于NSInvocationOperation

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            // 在这里更新UI
        }];


4.GCD

加载和更新UI都在一个方法里
    // 1) 获取全局队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    for (UIImageView *imageView in self.imageViewSet) {
        // 2) 在全局队列上异步调用方法,加载并更新图像
        dispatch_async(queue, ^{
            NSLog(@"GCD- %@", [NSThread currentThread]);
            
            NSInteger num = arc4random_uniform(17) + 1;
            NSString *imageName = [NSString stringWithFormat:@"NatGeo%02d.png", num];
            
            // 通常此处的image是从网络上获取的
            UIImage *image = [UIImage imageNamed:imageName];
            
            // 3) 在在主线程队列中,调用异步方法设置UI
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"更新图片- %@", [NSThread currentThread]);
                [imageView setImage:image];
            });
        });
    }













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值