JHHK

欢迎来到我的个人网站
行者常至 为者常成

GCD2

目录

sync相关Demo

先看队列是串行并行,再看执行时同步异步
放在串行队列里的任务一定是一个执行完再取下一个,是有顺序的
同步执行一定是整个任务块执行完再返回的

总结1: 只要在主线程执行 dispatch_sync(dispatch_get_main_queue(), ^{}); 必定会死锁
总结2:问题的关键是队列。
理解队列:串行队列里的任务只有前一个执行完才能取出后一个。
理解同步:同步是当前代码块执行完成之后才会返回。

- (IBAction)sync1:(id)sender {
    //global_queue - global_queue
    NSLog(@"current1  %@",[NSThread currentThread]);
    
    dispatch_sync(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
        NSLog(@"current2  %@",[NSThread currentThread]);

        dispatch_sync(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"current3  %@",[NSThread currentThread]);
        });
    });
    
    NSLog(@"current4  %@",[NSThread currentThread]);
    
    /**
     2022-04-02 00:10:41.798027+0800 XYApp[79949:3633423] current1  <_NSMainThread: 0x283228600>{number = 1, name = main}
     2022-04-02 00:10:41.798345+0800 XYApp[79949:3633423] current2  <_NSMainThread: 0x283228600>{number = 1, name = main}
     2022-04-02 00:10:41.798526+0800 XYApp[79949:3633423] current3  <_NSMainThread: 0x283228600>{number = 1, name = main}
     2022-04-02 00:10:41.798698+0800 XYApp[79949:3633423] current4  <_NSMainThread: 0x283228600>{number = 1, name = main}
     */
}


- (IBAction)sync2:(id)sender {
    //global_queue - main_queue
    NSLog(@"current1  %@",[NSThread currentThread]);
    
    dispatch_sync(dispatch_get_global_queue(0,0), ^{
        NSLog(@"current2  %@",[NSThread currentThread]);
        
        //死锁
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"current3  %@",[NSThread currentThread]);
        });
    });
    NSLog(@"current4  %@",[NSThread currentThread]);

    /**
     2022-04-02 00:12:04.476120+0800 XYApp[79949:3633423] current1  <_NSMainThread: 0x283228600>{number = 1, name = main}
     2022-04-02 00:12:04.476297+0800 XYApp[79949:3633423] current2  <_NSMainThread: 0x283228600>{number = 1, name = main}
     死锁
     */
}


- (IBAction)sync3:(id)sender {
    //main_queue - global_queue
    NSLog(@"current1  %@",[NSThread currentThread]);
    
    //死锁
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"current2  %@",[NSThread currentThread]);
        
        dispatch_sync(dispatch_get_global_queue(0,0), ^{
            NSLog(@"current3  %@",[NSThread currentThread]);
        });
    });
    
    NSLog(@"current4  %@",[NSThread currentThread]);

    /**
     2022-04-02 00:19:15.663318+0800 XYApp[80099:3637866] current1  <_NSMainThread: 0x280fe8880>{number = 1, name = main}
     死锁
     */
}



- (IBAction)sync4:(id)sender {
    //main_queue - main_queue
    NSLog(@"current1  %@",[NSThread currentThread]);
    
    //死锁
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"current2  %@",[NSThread currentThread]);
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"current3  %@",[NSThread currentThread]);
        });
    });
    
    NSLog(@"current4  %@",[NSThread currentThread]);

    /**
     2022-04-02 00:19:48.338190+0800 XYApp[80112:3638572] current1  <_NSMainThread: 0x282638880>{number = 1, name = main}
     */
}


//总结1: 只要在主线程执行  dispatch_sync(dispatch_get_main_queue(), ^{}); 必定会死锁


- (IBAction)sync5:(id)sender {
    
    [self subThreadWithDoneBlock:^{
        
        NSLog(@"current1  %@",[NSThread currentThread]);
        
        dispatch_sync(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
            NSLog(@"current2  %@",[NSThread currentThread]);

            dispatch_sync(dispatch_get_global_queue(0, 0), ^{
                NSLog(@"current3  %@",[NSThread currentThread]);
            });
        });
        
        NSLog(@"current4  %@",[NSThread currentThread]);
    }];
    
    NSLog(@"current5  %@",[NSThread currentThread]);
    
    /**
     2022-04-01 23:09:28.984252+0800 XYApp[78915:3603042] current5  <_NSMainThread: 0x283df0900>{number = 1, name = main}
     2022-04-01 23:09:28.984346+0800 XYApp[78915:3603244] current1  <NSThread: 0x283d82980>{number = 7, name = (null)}
     2022-04-01 23:09:28.984617+0800 XYApp[78915:3603244] current2  <NSThread: 0x283d82980>{number = 7, name = (null)}
     2022-04-01 23:09:28.984799+0800 XYApp[78915:3603244] current3  <NSThread: 0x283d82980>{number = 7, name = (null)}
     2022-04-01 23:09:28.984967+0800 XYApp[78915:3603244] current4  <NSThread: 0x283d82980>{number = 7, name = (null)}
     */
}



- (IBAction)sync6:(id)sender {
    [self subThreadWithDoneBlock:^{
        NSLog(@"current1  %@",[NSThread currentThread]);
        
        dispatch_sync(dispatch_get_global_queue(0,0), ^{
            NSLog(@"current2  %@",[NSThread currentThread]);
            
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"current3  %@",[NSThread currentThread]);
            });
        });
        NSLog(@"current4  %@",[NSThread currentThread]);
    }];
    NSLog(@"current5  %@",[NSThread currentThread]);
    sleep(2);
    NSLog(@"current6  %@",[NSThread currentThread]);

    /**
     2022-04-01 23:20:22.017079+0800 XYApp[79118:3610327] current5  <_NSMainThread: 0x280ea8880>{number = 1, name = main}
     2022-04-01 23:20:22.017094+0800 XYApp[79118:3610359] current1  <NSThread: 0x280ef8040>{number = 5, name = (null)}
     2022-04-01 23:20:22.017421+0800 XYApp[79118:3610359] current2  <NSThread: 0x280ef8040>{number = 5, name = (null)}
     2022-04-01 23:20:24.018549+0800 XYApp[79118:3610327] current6  <_NSMainThread: 0x280ea8880>{number = 1, name = main}
     2022-04-01 23:20:24.020729+0800 XYApp[79118:3610327] current3  <_NSMainThread: 0x280ea8880>{number = 1, name = main}
     2022-04-01 23:20:24.021011+0800 XYApp[79118:3610359] current4  <NSThread: 0x280ef8040>{number = 5, name = (null)}
     */
}



- (IBAction)sync7:(id)sender {
    [self subThreadWithDoneBlock:^{
        NSLog(@"current1  %@",[NSThread currentThread]);
        
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"current2  %@",[NSThread currentThread]);
            
            dispatch_sync(dispatch_get_global_queue(0,0), ^{
                NSLog(@"current3  %@",[NSThread currentThread]);
            });
        });
        NSLog(@"current4  %@",[NSThread currentThread]);
    }];
    NSLog(@"current5  %@",[NSThread currentThread]);

    /**
     2022-04-01 23:10:10.325155+0800 XYApp[78915:3603248] current1  <NSThread: 0x283db4000>{number = 8, name = (null)}
     2022-04-01 23:10:10.325152+0800 XYApp[78915:3603042] current5  <_NSMainThread: 0x283df0900>{number = 1, name = main}
     2022-04-01 23:10:10.326796+0800 XYApp[78915:3603042] current2  <_NSMainThread: 0x283df0900>{number = 1, name = main}
     2022-04-01 23:10:10.327032+0800 XYApp[78915:3603042] current3  <_NSMainThread: 0x283df0900>{number = 1, name = main}
     2022-04-01 23:10:10.327256+0800 XYApp[78915:3603248] current4  <NSThread: 0x283db4000>{number = 8, name = (null)}
     */
}


- (IBAction)sync8:(id)sender {
    [self subThreadWithDoneBlock:^{
        NSLog(@"current1  %@",[NSThread currentThread]);
        
        //死锁:current2 与 current3 在互相等待,所以造成死锁
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"current2  %@",[NSThread currentThread]);
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"current3  %@",[NSThread currentThread]);
            });
        });
        NSLog(@"current4  %@",[NSThread currentThread]);
    }];
    NSLog(@"current5  %@",[NSThread currentThread]);
    
    /**
     2022-04-01 23:10:26.489151+0800 XYApp[78915:3603042] current5  <_NSMainThread: 0x283df0900>{number = 1, name = main}
     2022-04-01 23:10:26.489154+0800 XYApp[78915:3603248] current1  <NSThread: 0x283db4000>{number = 8, name = (null)}
     2022-04-01 23:10:26.490770+0800 XYApp[78915:3603042] current2  <_NSMainThread: 0x283df0900>{number = 1, name = main}
     死锁
     */
}


- (IBAction)sync9:(id)sender {
    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueueTest", DISPATCH_QUEUE_SERIAL);
    
    NSLog(@"current1  %@",[NSThread currentThread]);
    
    dispatch_sync(serialQueue, ^{
        NSLog(@"current2  %@",[NSThread currentThread]);
        
        //在此处死锁,serialQueue的特点,任务应该按顺序取出执行。
        dispatch_sync(serialQueue, ^{
            NSLog(@"current3  %@",[NSThread currentThread]);
        });
    });
    
    NSLog(@"current4  %@",[NSThread currentThread]);
    
    /**
     2022-04-02 00:29:47.880105+0800 XYApp[80271:3642337] current1  <_NSMainThread: 0x280fd8880>{number = 1, name = main}
     2022-04-02 00:29:47.880478+0800 XYApp[80271:3642337] current2  <_NSMainThread: 0x280fd8880>{number = 1, name = main}
     死锁
     */
}


- (IBAction)sync10:(id)sender {
    NSLog(@"current1  %@",[NSThread currentThread]);
    //死锁
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"current2  %@",[NSThread currentThread]);
    });
    NSLog(@"current3  %@",[NSThread currentThread]);
    
    /**
     2022-04-02 00:30:18.805675+0800 XYApp[80283:3643093] current1  <_NSMainThread: 0x280cd4880>{number = 1, name = main}
     死锁
     */
}


//总结2:问题的关键是队列。理解队列,理解线程,理解同步(当前线程执行完block再返回)。

#pragma mark - 子线程
/// 在子线程执行block
/// @param block 任务
- (void)subThreadWithDoneBlock:(void(^)(void))block {
    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        if (block) { block();}
    }];
}




- (void)test {
    dispatch_queue_t queue = dispatch_queue_create("lxy-queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_get_label(queue);
}




- (void)dealloc {
    NSLog(@"lxy:%s",__func__);
}
@end

async相关Demo

- (IBAction)async1:(id)sender {
    //创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue, ^{
        NSLog(@"current1  %@",[NSThread currentThread]);
        
        dispatch_async(queue, ^{
            NSLog(@"current2  %@",[NSThread currentThread]);
        });
    });
    
    NSLog(@"current3  %@",[NSThread currentThread]);

    /**
     2022-04-02 23:27:46.457775+0800 XYApp[18862:12321559] current1  <_NSMainThread: 0x280280800>{number = 1, name = main}
     2022-04-02 23:27:46.458091+0800 XYApp[18862:12321559] current3  <_NSMainThread: 0x280280800>{number = 1, name = main}
     2022-04-02 23:27:46.458149+0800 XYApp[18862:12321571] current2  <NSThread: 0x2802ec280>{number = 7, name = (null)}
     */
    
}

- (IBAction)async2:(id)sender {
    
    dispatch_queue_t queue = dispatch_queue_create("SERIAL", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(queue, ^{
        NSLog(@"current1  %@",[NSThread currentThread]);
        
        //死锁
        dispatch_sync(queue, ^{
            NSLog(@"current2  %@",[NSThread currentThread]);
        });
    });
    
    NSLog(@"current3  %@",[NSThread currentThread]);
    
    /**
     2022-04-02 23:28:15.568690+0800 XYApp[18862:12321559] current3  <_NSMainThread: 0x280280800>{number = 1, name = main}
     2022-04-02 23:28:15.568787+0800 XYApp[18862:12321573] current1  <NSThread: 0x2802c7f00>{number = 3, name = (null)}
     死锁
     */

}

group相关Demo


- (IBAction)group1:(id)sender {
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_queue_t queue = dispatch_queue_create("xxx_concurrent", DISPATCH_QUEUE_CONCURRENT);
    
    
    dispatch_group_async(group,queue, ^{
        NSLog(@"current1  %@",[NSThread currentThread]);
    });

    NSLog(@"current2  %@",[NSThread currentThread]);

    dispatch_group_async(group,queue, ^{
        NSLog(@"current3  %@",[NSThread currentThread]);
    });
    
    NSLog(@"current4  %@",[NSThread currentThread]);
    
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"current5  %@",[NSThread currentThread]);
    });
    
    NSLog(@"current6  %@",[NSThread currentThread]);
    
    /**
     2022-04-03 19:04:52.666574+0800 XYApp[19180:12567570] current2  <_NSMainThread: 0x28022c800>{number = 1, name = main}
     2022-04-03 19:04:52.666588+0800 XYApp[19180:12567796] current1  <NSThread: 0x28027c6c0>{number = 8, name = (null)}
     2022-04-03 19:04:52.666833+0800 XYApp[19180:12567570] current4  <_NSMainThread: 0x28022c800>{number = 1, name = main}
     2022-04-03 19:04:52.666853+0800 XYApp[19180:12567796] current3  <NSThread: 0x28027c6c0>{number = 8, name = (null)}
     2022-04-03 19:04:52.666971+0800 XYApp[19180:12567570] current6  <_NSMainThread: 0x28022c800>{number = 1, name = main}
     2022-04-03 19:04:52.667020+0800 XYApp[19180:12567796] current5  <NSThread: 0x28027c6c0>{number = 8, name = (null)}
     */
    
}



- (IBAction)group2:(id)sender {
    
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("xxx_concurrent", DISPATCH_QUEUE_CONCURRENT);


    dispatch_group_enter(group);
    dispatch_group_enter(group);
    NSLog(@"current1  %@",[NSThread currentThread]);
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), queue, ^{
        dispatch_group_leave(group);
        NSLog(@"current2  %@",[NSThread currentThread]);
    });

    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 4 * NSEC_PER_SEC), queue, ^{
        dispatch_group_leave(group);
        NSLog(@"current3  %@",[NSThread currentThread]);
    });

    
    //enter 与 leave平衡 时调用
    dispatch_group_notify(group, queue, ^{
        NSLog(@"current4  %@",[NSThread currentThread]);
    });
    
    
    NSLog(@"current5  %@",[NSThread currentThread]);
    intptr_t result = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 6));
    if (result == 0) {
        //enter 与 leave平衡
        NSLog(@"current6  %@",[NSThread currentThread]);
    } else  {
        //超时
        NSLog(@"current7  %@",[NSThread currentThread]);
    }
    
    /**
     2022-04-03 22:26:11.785975+0800 XYApp[19254:12612960] current1  <_NSMainThread: 0x281b3c800>{number = 1, name = main}
     2022-04-03 22:26:11.786240+0800 XYApp[19254:12612960] current5  <_NSMainThread: 0x281b3c800>{number = 1, name = main}
     2022-04-03 22:26:13.892375+0800 XYApp[19254:12613141] current2  <NSThread: 0x281b68480>{number = 8, name = (null)}
     2022-04-03 22:26:16.017678+0800 XYApp[19254:12613141] current3  <NSThread: 0x281b68480>{number = 8, name = (null)}
     2022-04-03 22:26:16.017676+0800 XYApp[19254:12612960] current6  <_NSMainThread: 0x281b3c800>{number = 1, name = main}
     2022-04-03 22:26:16.017762+0800 XYApp[19254:12614026] current4  <NSThread: 0x281b49840>{number = 9, name = (null)}
     */
}

dispatch_barrier_(a)sync相关Demo

- (IBAction)barrierSync:(id)sender {
    dispatch_queue_t queue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
    //    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    
    dispatch_async(queue, ^{
        for (int i = 0; i<10000; i++) {}
        NSLog(@"current1  %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i<10000; i++) {}
        NSLog(@"current2  %@",[NSThread currentThread]);
    });
    
    dispatch_barrier_sync(queue, ^{
        NSLog(@"current3  %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"current4  %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"current5  %@",[NSThread currentThread]);
    });
    
    NSLog(@"current6  %@",[NSThread currentThread]);
    
    /**
     2022-04-03 23:05:07.407357+0800 XYApp[19279:12625839] current1  <NSThread: 0x280166300>{number = 4, name = (null)}
     2022-04-03 23:05:07.407354+0800 XYApp[19279:12625850] current2  <NSThread: 0x280128400>{number = 7, name = (null)}
     2022-04-03 23:05:07.407666+0800 XYApp[19279:12625823] current3  <_NSMainThread: 0x2801601c0>{number = 1, name = main}
     2022-04-03 23:05:07.407895+0800 XYApp[19279:12625823] current6  <_NSMainThread: 0x2801601c0>{number = 1, name = main}
     2022-04-03 23:05:07.407935+0800 XYApp[19279:12625839] current4  <NSThread: 0x280166300>{number = 4, name = (null)}
     2022-04-03 23:05:07.407938+0800 XYApp[19279:12625850] current5  <NSThread: 0x280128400>{number = 7, name = (null)}
     */
}


- (IBAction)barrierAsync:(id)sender {

    dispatch_queue_t queue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
    //    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i<10000; i++) {}
        NSLog(@"current1  %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i<10000; i++) {}
        NSLog(@"current2  %@",[NSThread currentThread]);
    });
    
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"current3  %@",[NSThread currentThread]);
    });
    
    
    dispatch_async(queue, ^{
        NSLog(@"current4  %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"current5  %@",[NSThread currentThread]);
    });
    
    NSLog(@"current6  %@",[NSThread currentThread]);
    
    /**
     2022-04-03 23:06:52.420299+0800 XYApp[19283:12626650] current6  <_NSMainThread: 0x280828800>{number = 1, name = main}
     2022-04-03 23:06:52.420419+0800 XYApp[19283:12626670] current1  <NSThread: 0x280842280>{number = 7, name = (null)}
     2022-04-03 23:06:52.420422+0800 XYApp[19283:12626667] current2  <NSThread: 0x280878080>{number = 3, name = (null)}
     2022-04-03 23:06:52.420666+0800 XYApp[19283:12626667] current3  <NSThread: 0x280878080>{number = 3, name = (null)}
     2022-04-03 23:06:52.420833+0800 XYApp[19283:12626667] current4  <NSThread: 0x280878080>{number = 3, name = (null)}
     2022-04-03 23:06:52.420872+0800 XYApp[19283:12626670] current5  <NSThread: 0x280842280>{number = 7, name = (null)}
     */
}


- (IBAction)lg_test1:(id)sender {
    dispatch_queue_t t = dispatch_queue_create("lg", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(t, ^{
        NSLog(@"1");
    });
    dispatch_async(t, ^{
        NSLog(@"2");
    });
    // 栅栏函数
    dispatch_barrier_async(t, ^{
        NSLog(@"3");
    });
    
    NSLog(@"4");
    dispatch_async(t, ^{
        NSLog(@"5");
    });
    
    
    /**
     2022-08-15 16:26:27.369083+0800 XYApp[26129:5845925] 4
     2022-08-15 16:26:27.369177+0800 XYApp[26129:5845946] 2
     2022-08-15 16:26:27.369107+0800 XYApp[26129:5845944] 1
     2022-08-15 16:26:27.369478+0800 XYApp[26129:5845944] 3
     2022-08-15 16:26:27.369597+0800 XYApp[26129:5845944] 5

     栅栏函数只能拦住当前的自定义队列。
     这个是异步栅栏函数
     */
}



- (IBAction)lg_test2:(id)sender {
    dispatch_queue_t t = dispatch_queue_create("lg", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(t, ^{
        NSLog(@"1");
    });
    dispatch_async(t, ^{
        NSLog(@"2");
    });
    // 栅栏函数
    dispatch_barrier_sync(t, ^{
        NSLog(@"3");
    });
    
    NSLog(@"4");
    dispatch_async(t, ^{
        NSLog(@"5");
    });
    
    
    /**
     2022-08-15 16:29:21.926389+0800 XYApp[26159:5846955] 2
     2022-08-15 16:29:21.926382+0800 XYApp[26159:5846960] 1
     2022-08-15 16:29:21.926656+0800 XYApp[26159:5846933] 3
     2022-08-15 16:29:21.926783+0800 XYApp[26159:5846933] 4
     2022-08-15 16:29:21.926939+0800 XYApp[26159:5846955] 5

     栅栏函数只能拦住当前的自定义队列。
     这个是同步栅栏函数
     */
}

perform相关Demo

主线程执行perform相关方法的情况

// 依赖runloop,处理source0时处理
[self performSelector:@selector(test4)];
[self performSelector:@selector(test5:) withObject:@"hehe"];
// 阻塞当前线程,直到test1执行完成
[self performSelector:@selector(test1) onThread:currentThread withObject:nil waitUntilDone:YES];
// 不会阻塞当前线程,立即返回
[self performSelector:@selector(test1) onThread:currentThread withObject:nil waitUntilDone:NO];


// 依赖runloop,处理timer时处理
[self performSelector:@selector(test1) withObject:nil afterDelay:0];

子线程执行perform相关方法的情况

// 以下情况不依赖运行循环。会在当前线程立即调用
[self performSelector:@selector(test4)];
[self performSelector:@selector(test5:) withObject:@"hehe"];
//阻塞当前线程,直到test1执行完成
[self performSelector:@selector(test1) onThread:currentThread withObject:nil waitUntilDone:YES];
 

// 下面perform开头的方法都会依赖运行循环。在没有开启运行循环的线程里是没发执行的。
[self performSelector:@selector(test1) onThread:currentThread withObject:nil waitUntilDone:NO];
[self performSelector:@selector(test1) withObject:nil afterDelay:0];
 

另外performSelector:withObject:afterDelay: dispatch_after 都是立即返回。当两者延迟都是0,前者的执行时机比后者慢,因为前者依赖运行循环。
- (IBAction)perform1:(id)sender {
    //发送指定的消息给接收者,并返回消息的结果。
    id value = [self performSelector:@selector(test1)];
    NSLog(@"value = %@",value);
}



- (IBAction)perform2:(id)sender {
    // 依赖运行循环
    [self performSelector:@selector(test2) withObject:nil afterDelay:2];
    NSLog(@"点击了");
}



- (IBAction)perform3:(id)sender {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [self test1];
        });
        [self test2];
        
        
        [self performSelector:@selector(test3) withObject:nil afterDelay:0];
        
        [self performSelector:@selector(test4)];
    });
    
    /**
     2022-08-19 11:38:40.782299+0800 XYApp[49097:6801088] test2
     2022-08-19 11:38:40.782572+0800 XYApp[49097:6801088] <NSThread: 0x281824740>{number = 9, name = (null)}
     2022-08-19 11:38:40.782761+0800 XYApp[49097:6801088] test4
     2022-08-19 11:38:40.782929+0800 XYApp[49097:6801088] <NSThread: 0x281824740>{number = 9, name = (null)}
     2022-08-19 11:38:40.783368+0800 XYApp[49097:6798449] test1
     2022-08-19 11:38:40.783597+0800 XYApp[49097:6798449] <_NSMainThread: 0x281868880>{number = 1, name = main}
     
     test3不会执行的原因是它需要依赖运行循环
     */
}


- (IBAction)perform4:(id)sender {
    [self performSelector:@selector(test1) withObject:nil afterDelay:0];
    [self performSelector:@selector(test2)];
    
    /**
     2022-08-19 11:42:13.042556+0800 XYApp[49265:6803674] test2
     2022-08-19 11:42:13.042865+0800 XYApp[49265:6803674] <_NSMainThread: 0x280934880>{number = 1, name = main}
     2022-08-19 11:42:13.044302+0800 XYApp[49265:6803674] test1
     2022-08-19 11:42:13.044531+0800 XYApp[49265:6803674] <_NSMainThread: 0x280934880>{number = 1, name = main}
     
     为什么2会在1的前面。因为2会直接调用。1要等待runloop的调度。1就是一个定时器依赖于runloop
     */
}


- (IBAction)perform5:(id)sender {
    
    // Yes需要等待执行完成,test1会直接被调用
    [self performSelectorOnMainThread:@selector(test1) withObject:nil waitUntilDone:YES];
    NSLog(@"点击了1");
    
    // No不需要等待执行完成,test2的调用依赖运行循环
    [self performSelectorOnMainThread:@selector(test2) withObject:nil waitUntilDone:NO];
    NSLog(@"点击了2");
    
    
    /**
     2022-08-19 11:46:25.101312+0800 XYApp[49317:6805977] test1
     2022-08-19 11:46:25.101611+0800 XYApp[49317:6805977] <_NSMainThread: 0x282af8900>{number = 1, name = main}
     2022-08-19 11:46:25.101789+0800 XYApp[49317:6805977] 点击了1
     2022-08-19 11:46:25.101997+0800 XYApp[49317:6805977] 点击了2
     2022-08-19 11:46:25.103614+0800 XYApp[49317:6805977] test2
     2022-08-19 11:46:25.103874+0800 XYApp[49317:6805977] <_NSMainThread: 0x282af8900>{number = 1, name = main}
     */
    
}



- (IBAction)perform6:(id)sender {
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self performSelector:@selector(test1) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];
        NSLog(@"点击了1");

        [self performSelector:@selector(test2)];
        NSLog(@"点击了2");

        [self performSelector:@selector(test3) onThread:[NSThread currentThread] withObject:nil waitUntilDone:NO];//NO 依赖运行循环
        NSLog(@"点击了3");

        NSThread *otherThread = [[NSThread alloc] init];
        [self performSelector:@selector(test4) onThread:otherThread withObject:nil waitUntilDone:NO];//NO 依赖运行循环
        NSLog(@"点击了4");
    });
    
    /**
     2023-12-08 15:43:40.088949+0800 XYApp[57744:2346790] test1
     2023-12-08 15:43:40.090063+0800 XYApp[57744:2346790] <NSThread: 0x60000229fe40>{number = 7, name = (null)}
     2023-12-08 15:43:40.091394+0800 XYApp[57744:2346790] 点击了1
     2023-12-08 15:43:40.091769+0800 XYApp[57744:2346790] test2
     2023-12-08 15:43:40.092076+0800 XYApp[57744:2346790] <NSThread: 0x60000229fe40>{number = 7, name = (null)}
     2023-12-08 15:43:40.092220+0800 XYApp[57744:2346790] 点击了2
     2023-12-08 15:43:40.094218+0800 XYApp[57744:2346790] 点击了3
     2023-12-08 15:43:40.094407+0800 XYApp[57744:2346790] 点击了4
     */
}




- (IBAction)perform7:(id)sender {
    
    Discussion
    这个方法与performSelector相同:不同的是你可以为selector提供一个参数。
    选择器应该识别一个接受id类型参数的方法。对于具有其他参数类型和返回值的方法,使用NSInvocation
     

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        id result = [self performSelector:@selector(test5:) withObject:@"hehe"];
//        NSLog(@"lxy:resutl = %@",result);
        
        [self performSelector:@selector(test5:) withObject:@"hehe"];

    });
    
    /**
     2023-12-08 15:45:23.251647+0800 XYApp[57744:2345279] test5:
     2023-12-08 15:45:23.253822+0800 XYApp[57744:2345279] <NSThread: 0x600002292200>{number = 9, name = (null)}
     2023-12-08 15:45:23.253998+0800 XYApp[57744:2345279] lxy:hehe
     */
}

interview

- (IBAction)interview1:(id)sender {
    //并发队列的封装
    //NSOperation涉及到队列了就是异步调用
    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"current1  %@",[NSThread currentThread]);
        });
        NSLog(@"current2  %@",[NSThread currentThread]);
    }];
    NSLog(@"current3  %@",[NSThread currentThread]);
    
    /**
     2022-08-19 11:15:18.551589+0800 XYApp[48990:6795163] current3  <_NSMainThread: 0x280ba0880>{number = 1, name = main}
     2022-08-19 11:15:18.553367+0800 XYApp[48990:6795163] current1  <_NSMainThread: 0x280ba0880>{number = 1, name = main}
     2022-08-19 11:15:18.553674+0800 XYApp[48990:6795315] current2  <NSThread: 0x280bed740>{number = 3, name = (null)}
     */
}


- (IBAction)interview2:(id)sender {
    dispatch_queue_t aSerialQueue = dispatch_queue_create("xxx_name", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(aSerialQueue, ^{
        NSLog(@"current1  %@",[NSThread currentThread]);
        sleep(2);
    });
    

    dispatch_sync(aSerialQueue, ^{
        NSLog(@"current2  %@",[NSThread currentThread]);
        sleep(2);
    });
    
    NSLog(@"current3  %@",[NSThread currentThread]);
    sleep(2);
    NSLog(@"current4  %@",[NSThread currentThread]);
    
    /**
     2022-04-09 14:26:39.683314+0800 XYApp[20647:13316962] current1  <NSThread: 0x2816dcb80>{number = 5, name = (null)}
     2022-04-09 14:26:41.684684+0800 XYApp[20647:13316951] current2  <_NSMainThread: 0x28168c1c0>{number = 1, name = main}
     2022-04-09 14:26:43.686054+0800 XYApp[20647:13316951] current3  <_NSMainThread: 0x28168c1c0>{number = 1, name = main}
     2022-04-09 14:26:45.687427+0800 XYApp[20647:13316951] current4  <_NSMainThread: 0x28168c1c0>{number = 1, name = main}
     */
    
}


- (IBAction)interview3:(id)sender {
    
    dispatch_queue_t serialQueue1 = dispatch_queue_create("xxx_name", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serialQueue1, ^{
        NSLog(@"current1  %@",[NSThread currentThread]);
        sleep(2);
    });
    
    dispatch_queue_t serialQueue2 = dispatch_queue_create("xxx_other_name", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(serialQueue2, ^{
        NSLog(@"current2  %@",[NSThread currentThread]);
        sleep(2);
    });
    
    
    NSLog(@"current3  %@",[NSThread currentThread]);
    sleep(2);
    NSLog(@"current4  %@",[NSThread currentThread]);
    
    /**
     2022-04-09 14:32:05.722065+0800 XYApp[20653:13318742] current1  <NSThread: 0x2815d0b80>{number = 4, name = (null)}
     2022-04-09 14:32:05.722067+0800 XYApp[20653:13318724] current2  <_NSMainThread: 0x2815981c0>{number = 1, name = main}
     2022-04-09 14:32:07.723435+0800 XYApp[20653:13318724] current3  <_NSMainThread: 0x2815981c0>{number = 1, name = main}
     2022-04-09 14:32:09.724825+0800 XYApp[20653:13318724] current4  <_NSMainThread: 0x2815981c0>{number = 1, name = main}
     */
}


#pragma mark - ingerview4 小米面试题
-(void)test1{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)test2{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)test3{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)test4{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)test5{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)test6{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)test7{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)test8{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}


-(void)testA{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

-(void)testB{
    NSLog(@"%@",NSStringFromSelector(_cmd));
}




- (IBAction)interview4:(id)sender {
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [self test1];//主队列排队
    });
    
    
    [self performSelector:@selector(test2) withObject:nil afterDelay:0];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self test3];//主队列排队:是在指定时间之后将任务追加到主队列中
    });
    
    
    
    [self performSelector:@selector(test4)];//当前线程立即执行

    [self test5];//当前线程立即执行
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [self test6];//主队列排队
        });
        [self test7];
        
        [self performSelector:@selector(test8) withObject:nil afterDelay:0];//依赖线程的运行循环,所以不会执行
    });
    
    
    /**
     2022-08-19 12:27:15.094636+0800 XYApp[49643:6816750] test4
     2022-08-19 12:27:15.094888+0800 XYApp[49643:6816750] test5
     2022-08-19 12:27:15.095116+0800 XYApp[49643:6816968] test7
     2022-08-19 12:27:15.096323+0800 XYApp[49643:6816750] test1
     2022-08-19 12:27:15.096513+0800 XYApp[49643:6816750] test3
     2022-08-19 12:27:15.096664+0800 XYApp[49643:6816750] test6
     2022-08-19 12:27:15.096876+0800 XYApp[49643:6816750] test2

     
     //如果将执行test3的延迟改为3秒,打印顺序如下
     2022-08-19 12:32:51.156387+0800 XYApp[49790:6822158] test4
     2022-08-19 12:32:51.156642+0800 XYApp[49790:6822158] test5
     2022-08-19 12:32:51.156919+0800 XYApp[49790:6822177] test7
     2022-08-19 12:32:51.158391+0800 XYApp[49790:6822158] test1
     2022-08-19 12:32:51.158598+0800 XYApp[49790:6822158] test6
     2022-08-19 12:32:51.158820+0800 XYApp[49790:6822158] test2
     2022-08-19 12:32:54.368531+0800 XYApp[49790:6822158] test3
     */
}


#pragma mark - 逻辑教育 - 220520-第十一节课-多线程(上)- 003--gcd面试题小试_ev.ev4a
- (IBAction)interview5:(id)sender {
    dispatch_queue_t queue = dispatch_queue_create("lxyCONCURRENT", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"lxy:1");
    
    dispatch_async(queue, ^{
        NSLog(@"lxy:2");
        dispatch_sync(queue, ^{
            NSLog(@"lxy:3");
        });
        NSLog(@"lxy:4");
    });
    
    NSLog(@"lxy:5");
    
    /**
     2022-08-15 12:36:13.523604+0800 XYApp[23880:5775282] lxy:1
     2022-08-15 12:36:13.524032+0800 XYApp[23880:5775282] lxy:5
     2022-08-15 12:36:13.524059+0800 XYApp[23880:5775304] lxy:2
     2022-08-15 12:36:13.524205+0800 XYApp[23880:5775304] lxy:3
     2022-08-15 12:36:13.524318+0800 XYApp[23880:5775304] lxy:4
     */
}


- (IBAction)interview6:(id)sender {
    dispatch_queue_t queue = dispatch_queue_create("lxySERIAL", DISPATCH_QUEUE_SERIAL);
    NSLog(@"lxy:1");
    
    dispatch_async(queue, ^{
        NSLog(@"lxy:2");
        dispatch_sync(queue, ^{
            NSLog(@"lxy:3");
        });
        NSLog(@"lxy:4");
    });
    NSLog(@"lxy:5");
    
    /**
     2022-08-15 12:37:04.020600+0800 XYApp[23880:5775282] lxy:1
     2022-08-15 12:37:04.020747+0800 XYApp[23880:5775282] lxy:5
     2022-08-15 12:37:04.020767+0800 XYApp[23880:5775305] lxy:2
     死锁
     */
}


- (IBAction)interview7:(id)sender {
    dispatch_queue_t queue = dispatch_queue_create("lxySERIAL2", DISPATCH_QUEUE_SERIAL);
    NSLog(@"lxy:1");
    
    dispatch_async(queue, ^{
        NSLog(@"lxy:2");
        dispatch_async(queue, ^{
            NSLog(@"lxy:3");
        });
        sleep(2);
        NSLog(@"lxy:4");
    });
    NSLog(@"lxy:5");
    
    /**
     2022-08-15 12:36:28.922395+0800 XYApp[23880:5775282] lxy:1
     2022-08-15 12:36:28.922661+0800 XYApp[23880:5775282] lxy:5
     2022-08-15 12:36:28.922692+0800 XYApp[23880:5775305] lxy:2
     2022-08-15 12:36:30.927994+0800 XYApp[23880:5775305] lxy:4
     2022-08-15 12:36:30.928296+0800 XYApp[23880:5775305] lxy:3
     */
}


- (IBAction)interview8:(id)sender {
    dispatch_queue_t queue = dispatch_queue_create("lxySERIAL3", DISPATCH_QUEUE_SERIAL);
    NSLog(@"lxy:1");
    dispatch_async(queue, ^{
        NSLog(@"lxy:2");
        dispatch_async(queue, ^{
            NSLog(@"lxy:3");
        });
        NSLog(@"lxy:4");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"lxy:6");
    });
    NSLog(@"lxy:7");
    
    /**
     2022-08-15 13:59:03.670171+0800 XYApp[24614:5799376] lxy:1
     2022-08-15 13:59:03.670557+0800 XYApp[24614:5799376] lxy:7
     2022-08-15 13:59:03.670581+0800 XYApp[24614:5799543] lxy:2
     2022-08-15 13:59:03.670736+0800 XYApp[24614:5799543] lxy:4
     2022-08-15 13:59:03.670847+0800 XYApp[24614:5799543] lxy:6
     2022-08-15 13:59:03.670949+0800 XYApp[24614:5799543] lxy:3
     */
}


- (IBAction)interview9:(id)sender {
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_sync(queue, ^{
        NSLog(@"lxy:1");
    });
    
    /**
     死锁
     */
}



#pragma mark - 逻辑教育 - 220520-第十二节课-多线程(中)

- (IBAction)lg_test1:(id)sender {
    dispatch_queue_t queue = dispatch_queue_create("zxy", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"1");
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
    });
    dispatch_sync(queue, ^{
        NSLog(@"3");
    });
    NSLog(@"0");
    dispatch_async(queue, ^{
        NSLog(@"7");
    });
    dispatch_async(queue, ^{
        NSLog(@"8");
    });
    dispatch_async(queue, ^{
        NSLog(@"9");
    });
    
    /**
     2022-08-15 15:59:19.093210+0800 XYApp[25833:5837021] 3
     2022-08-15 15:59:19.093312+0800 XYApp[25833:5837021] 0
     2022-08-15 15:59:19.093394+0800 XYApp[25833:5837761] 1
     2022-08-15 15:59:19.093461+0800 XYApp[25833:5837761] 2
     2022-08-15 15:59:19.093582+0800 XYApp[25833:5837786] 7
     2022-08-15 15:59:19.094239+0800 XYApp[25833:5837787] 8
     2022-08-15 15:59:19.094262+0800 XYApp[25833:5837761] 9

     */
}

- (IBAction)lg_test2:(id)sender {
    dispatch_queue_t t = dispatch_queue_create("lg", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"1");
    dispatch_sync(t, ^{
        NSLog(@"2");
        dispatch_async(t, ^{
            NSLog(@"3");
        });
        NSLog(@"4");
    });
    NSLog(@"5");
    
    /**
     2022-08-15 16:01:51.618838+0800 XYApp[25881:5838957] 1
     2022-08-15 16:01:51.619065+0800 XYApp[25881:5838957] 2
     2022-08-15 16:01:51.619206+0800 XYApp[25881:5838957] 4
     2022-08-15 16:01:51.619246+0800 XYApp[25881:5838984] 3
     2022-08-15 16:01:51.619310+0800 XYApp[25881:5838957] 5
     */
}

- (IBAction)lg_test3:(id)sender {
    self.num = 0;
    int time = 0;
    while (self.num < 100) {
        time ++;
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            self.num ++;
            //self.num = self.num + 1;
        });
    }
    NSLog(@"self.num = %d",self.num);
    NSLog(@"time = %d",time);
    /**
     肯定会 >= 100
     2022-08-15 16:01:48.269255+0800 XYApp[25881:5838957] self.num = 102
     2022-10-11 11:40:28.179999+0800 XYTestModule_Example[57853:4429651] time = 555
     */
}

- (IBAction)lg_test4:(id)sender {
    self.num = 0;
    for (int i = 0; i < 100; i ++) {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            self.num ++;
        });
    }
    NSLog(@"self.num = %d",self.num);
    
    /**
     肯定会<=100
     2022-08-15 16:03:43.624062+0800 XYApp[25881:5838957] self.num = 79
     */
}


-(IBAction)lg_test5:(id)sender {
    
    dispatch_queue_t t = dispatch_queue_create("lg", DISPATCH_QUEUE_SERIAL);
    NSLog(@"1");
    dispatch_sync(t, ^{
        NSLog(@"2");
        dispatch_async(t, ^{
            NSLog(@"3");
        });
        NSLog(@"4");
    });
    NSLog(@"5");
    
    /**
     2022-08-15 16:04:48.750428+0800 XYApp[25881:5838957] 1
     2022-08-15 16:04:48.750622+0800 XYApp[25881:5838957] 2
     2022-08-15 16:04:48.750747+0800 XYApp[25881:5838957] 4
     2022-08-15 16:04:48.750867+0800 XYApp[25881:5838957] 5
     2022-08-15 16:04:48.750905+0800 XYApp[25881:5839523] 3
     */
}

-(IBAction)lg_test6:(id)sender {
    dispatch_queue_t t = dispatch_queue_create("lg", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"1");
    dispatch_async(t, ^{
        NSLog(@"2");
        dispatch_sync(t, ^{
            NSLog(@"3");
        });
        NSLog(@"4");
    });
    NSLog(@"5");
    /**
     2022-08-15 16:07:17.535310+0800 XYApp[25881:5838957] 1
     2022-08-15 16:07:17.535528+0800 XYApp[25881:5838957] 5
     2022-08-15 16:07:17.535564+0800 XYApp[25881:5839523] 2
     2022-08-15 16:07:17.535712+0800 XYApp[25881:5839523] 3
     2022-08-15 16:07:17.535819+0800 XYApp[25881:5839523] 4
     */
}


@end

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.