美文网首页iOS 深度好文
IOS基础之切回到主线程的N种方式

IOS基础之切回到主线程的N种方式

作者: L63C | 来源:发表于2018-12-01 19:10 被阅读0次

    方式一:GCD (最常用)

    使用GCD又有2种方式:异步回到主线程和同步回到主线程。2种方式的差别在于是否会阻塞原来的线程。
    见下方的代码和日志

    异步回到主线程(建议使用)

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 需要在主线程执行的代码
        });
    

    深入了解:
    原来线程和主线程并行执行,即:系统会来回切换这2个线程,看起来像2个线程同时在执行

       NSLog(@"开启一个异步线程");
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"正在执行子线程中的代码");
            sleep(1);
            NSLog(@"准备回到主线程");
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"开始执行main线程中的代码");
                sleep(1);
                NSLog(@"继续执行main线程中的代码");
                sleep(1);
                NSLog(@"继续执行main线程中的代码");
                sleep(1);
                NSLog(@"继续执行main线程中的代码");
                NSLog(@"main线程中的代码执行完毕");
            });
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"子线程中代码执行完成");
        });
        NSLog(@"完成");
    
    2018-12-01 18:44:06.065959+0800 TestApp[4013:192606] 开启一个异步线程
    2018-12-01 18:44:06.066561+0800 TestApp[4013:192606] 完成
    2018-12-01 18:44:06.066609+0800 TestApp[4013:192685] 正在执行子线程中的代码
    2018-12-01 18:44:07.072672+0800 TestApp[4013:192685] 准备回到主线程
    2018-12-01 18:44:07.073054+0800 TestApp[4013:192685] 继续执行子线程中的代码
    2018-12-01 18:44:07.073087+0800 TestApp[4013:192606] 开始执行main线程中的代码
    2018-12-01 18:44:08.074562+0800 TestApp[4013:192685] 继续执行子线程中的代码
    2018-12-01 18:44:08.074564+0800 TestApp[4013:192606] 继续执行main线程中的代码
    2018-12-01 18:44:09.076120+0800 TestApp[4013:192606] 继续执行main线程中的代码
    2018-12-01 18:44:09.078331+0800 TestApp[4013:192685] 继续执行子线程中的代码
    2018-12-01 18:44:10.077170+0800 TestApp[4013:192606] 继续执行main线程中的代码
    2018-12-01 18:44:10.077491+0800 TestApp[4013:192606] main线程中的代码执行完毕
    2018-12-01 18:44:10.078793+0800 TestApp[4013:192685] 继续执行子线程中的代码
    2018-12-01 18:44:11.084351+0800 TestApp[4013:192685] 子线程中代码执行完成
    
    

    同步回到主线程

    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 需要在主线程执行的代码
        });
    

    深入了解
    原来线程和主线程 串行执行,即:中断正在执行的子线程,先回到主线程把需要执行的代码执行完后,再重新回到子线程继续执行。

     NSLog(@"开启一个异步线程");
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"正在执行子线程中的代码");
            sleep(1);
            NSLog(@"准备回到主线程");
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"开始执行main线程中的代码");
                sleep(1);
                NSLog(@"继续执行main线程中的代码");
                sleep(1);
                NSLog(@"继续执行main线程中的代码");
                sleep(1);
                NSLog(@"继续执行main线程中的代码");
                NSLog(@"main线程中的代码执行完毕");
            });
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"继续执行子线程中的代码");
            sleep(1);
            NSLog(@"子线程中代码执行完成");
        });
        NSLog(@"完成");
    
    2018-12-01 18:51:14.045142+0800 TestApp[4146:198711] 开启一个异步线程
    2018-12-01 18:51:14.048935+0800 TestApp[4146:198711] 完成
    2018-12-01 18:51:14.048965+0800 TestApp[4146:199189] 正在执行子线程中的代码
    2018-12-01 18:51:15.055313+0800 TestApp[4146:199189] 准备回到主线程
    2018-12-01 18:51:15.055767+0800 TestApp[4146:198711] 开始执行main线程中的代码
    2018-12-01 18:51:16.057238+0800 TestApp[4146:198711] 继续执行main线程中的代码
    2018-12-01 18:51:17.058822+0800 TestApp[4146:198711] 继续执行main线程中的代码
    2018-12-01 18:51:18.059647+0800 TestApp[4146:198711] 继续执行main线程中的代码
    2018-12-01 18:51:18.059980+0800 TestApp[4146:198711] main线程中的代码执行完毕
    2018-12-01 18:51:18.060323+0800 TestApp[4146:199189] 继续执行子线程中的代码
    2018-12-01 18:51:19.060857+0800 TestApp[4146:199189] 继续执行子线程中的代码
    2018-12-01 18:51:20.066423+0800 TestApp[4146:199189] 继续执行子线程中的代码
    2018-12-01 18:51:21.071962+0800 TestApp[4146:199189] 继续执行子线程中的代码
    2018-12-01 18:51:22.077000+0800 TestApp[4146:199189] 子线程中代码执行完成
    
    

    方式二:NSOperationQueue

    //这种方式等同于 GCD 方式中的异步回到主线程方式

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                //需要在主线程执行的代码
    }];
    

    方式三:performSelectorOnMainThread

    withObject: 用来传递需要传会主线程的的参数
    waitUntilDone:NO等价于GCD方式的异步回到主线程,YES等价于GCD方式中的同步回到主线程

    [self performSelectorOnMainThread:@selector(WantToGoBackMianThread:) withObject:@"1" waitUntilDone:YES];
    
    - (void)WantToGoBackMianThread:(id)object{
         //需要在主线程执行的代码
        NSLog(@"object:%@",object);
    }
    

    相关文章

      网友评论

        本文标题:IOS基础之切回到主线程的N种方式

        本文链接:https://www.haomeiwen.com/subject/uhvrcqtx.html