IOS中线程小笔记

小笔记:个人使用。保证只有自己看得懂~

在iOS中开启线程有三种方式

NSThread,GCD,NSOperation

其实还有一种,pthread ,只是这种太古老了,用起来难度大,所以被忽略了

1.NSThread

开线程方式:

//打开一个线程
-(void)newThread{

    //方式1:
    //withObject 参数,即run 方法的参数
    //[self performSelectorInBackground:@selector(run) withObject:nil];
    
    //方式2:
    //[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
    
    //方式3: 通过创建NSThread方式
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
    thread.name = @"thread-name-01";
    [thread start];
}

//执行完任务回到主线程

-(void)run{
    // to do
    //.....
    NSLog(@"%@",[NSThread currentThread]);
    
    //回到主线程
    //方式1:
    //[self performSelector:@selector(updateUI) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
    //方式2:
    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
    
}

-(void)updateUI{
    
    NSLog(@"%@",[NSThread currentThread]);

}

2. GCD

gcd执行任务:
gcd 执行任务有两个函数:

//异步
dispatch_async(dispatch_queue_t queue, dispatch_block_t block)
//同步
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block)

备注:好好理解异步、跟同步意思,所以一个任务如果交给gcd 同步函数执行任务了,都“同步”了,你说还会开启新的线程吗?
执行任务的函数里第一个参数是队列:

//主队列
 //dispatch_queue_t queue = dispatch_get_main_queue();
//创建一个队列
 //dispatch_queue_t queue = dispatch_queue_create("queue name", NULL); 
 //全局并发队列
 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

备注:
执行任务函数跟队列如何结合使用,决定着是否有新线程开启,是否并发等。
主队列看该方法名字dispatch_get_main_queue,“main”,所以在主队列执行任务的不管采用什么执行函数,都不会开线程
所以能开线程应是异步函数,至于是否并发就取决于队列。
所以一定要在理解的基础上进行记忆,切勿死记硬背。

-(void)gcd1{

    //异步任务、同步任务 (dispatch_async,dispatch_sync)
    
    //dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
    
    //dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
    
    //=============================================================
    //队列
    
    //主队列
    //dispatch_queue_t queue = dispatch_get_main_queue();
    
    //创建一个队列
    //dispatch_queue_t queue = dispatch_queue_create("queue name", NULL);
    
    //全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
       
        NSLog(@"执行任务.....%@",[NSThread currentThread]);
    });
    
}


这里采用网上一张图来更加形象的描述其情况



gcd线程间通信

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        
         NSLog(@"执行任务.....%@",[NSThread currentThread]);
        //执行任务.....<NSThread: 0x7fab9a5d2840>{number = 2, name = (null)}

        //back to mainthread update
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSLog(@"update.....%@",[NSThread currentThread]);
            //update.....<NSThread: 0x7fab9a401720>{number = 1, name = main}
        });
    });

gcd功能太强大,太多了,这里只是描述了两个函数的使用,其他使用可参考这个 文档

3.NsOperation

NSOperation是一个抽象类,因此在使用时需用起两个子类

NSInvocationOperation
NSBlockOperation

与NSOperation相关的还有一个很重要的类,NSOperationQueue,根据其名字也知道用来干啥用~

对于NSInvocationOperation用起操作时,如果没有加入NSOperationQueue队列中是不会开启新线程的,其任务还是在主线程中。

-(void)test1{
    //不会开启一个线程
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];
    [operation start];
}

-(void)run{
    NSLog(@"%@",[NSThread currentThread]);
}


对于NSBlockOperation如果没有NSOperationQueue队列中,是否开启线程取决于其任务有多少个,比如如果就一个任务,就不会开启线程,如果有多个任务就会开启多个线程。

-(void)test2{

    //NSBlockOperation 是否开线程取决于是否有几个任务
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A:%@-",[NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
         NSLog(@"A:%@-",[NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
        NSLog(@"A:%@-",[NSThread currentThread]);
    }];
    
    [operation start];
}

加入队列的情况:

-(void)test3{

    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    //添加到队里了,会开线程,开几条线程取决于有几个任务
    [queue addOperation:operation1];
    [queue addOperation:operation2];
}

最后一个NSOperation知识点,就是操作依赖,比如两个线程要执行两个任务A,B;其中B任务的执行必须在A完成后,类似这种就是所谓的操作依赖,NSOperation可用起addDependency进行处理

//操作依赖
-(void)test4{
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
       
        for (int i = 0; i < 10 ; i++) {
             NSLog(@"doing A :%d-%@",i,[NSThread currentThread]);
        }
    }];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 20 ; i++) {
            NSLog(@"doing B :%d-%@",i,[NSThread currentThread]);
        }
    }];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    //operation2 依赖于 operation1,operation1执行完才能执行operation2
    [operation2 addDependency:operation1];
    [queue addOperation:operation1];
    [queue addOperation:operation2];
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值