這里的阻塞主線程盗扇,并不是真正的卡死,而是利用
runloop
讓主線程等待。
舉例:我有三個方法需要依次執(zhí)行testLogOne
testLogTwo
testLogThree
,但是方法二testLogTwo
中是有block
或者是block 中有返回值的
醇锚,方法三testLogThree
需要等待方法二的block
回調完成后才能執(zhí)行。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self testLogOne];
[self testLogTwo:^{
NSLog(@"----2----");
}];
[self testLogThree];
}
/// 方法一
- (void)testLogOne {
NSLog(@"----1----");
}
/// 方法二
/// @param twoBlock 回調
- (void)testLogTwo:(void(^)(void))twoBlock {
dispatch_async(dispatch_get_main_queue(), ^{
if (twoBlock) {
twoBlock();
}
});
}
/// 方法三
- (void)testLogThree {
NSLog(@"----3----");
}
控制臺輸出
2021-03-16 18:04:41.691889+0800 demo[45188:559343] ----1----
2021-03-16 18:04:41.692060+0800 demo[45188:559343] ----3----
2021-03-16 18:04:41.714916+0800 demo[45188:559343] ----2----
使用信號量dispatch_semaphore_t ?
使用信號量dispatch_semaphore_t
會直接卡死主線程坯临,永遠等待不到信號的的接收焊唬。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
/// 卡主線程
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self testLogOne];
[self testLogTwo:^{
NSLog(@"----2----");
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[self testLogThree];
}
使用dispatch_group_t ??
使用dispatch_group_t
也可以將方法三testLogThree
,放到dispatch_group_notify
中執(zhí)行看靠,但是赶促,考慮到實際情況下,其他方法可能要比方法三testLogThree
先執(zhí)行挟炬,所有也放棄了此用法的考慮鸥滨。雖然可以將方法三testLogThree
放到block
中嗦哆,但是如果有其他特殊情況,例如for循環(huán)
爵赵,這樣也是不可取的吝秕。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
dispatch_group_t group = dispatch_group_create();
[self testLogOne];
for (NSInteger i = 0; i < 10; i ++) {
dispatch_group_enter(group);
[self testLogTwo:^{
NSLog(@"----2----");
dispatch_group_leave(group);
}];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"----2----after");
//[self testLogThree];
});
[self testLogThree];
}
控制臺輸出
2021-03-16 18:15:47.571770+0800 demo[48810:577013] ----1----
2021-03-16 18:15:47.572034+0800 demo[48810:577013] ----3----
2021-03-16 18:15:47.588403+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.588557+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.588653+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.588736+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.588830+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.588919+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.589213+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.589303+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.589590+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.589831+0800 demo[48810:577013] ----2----
2021-03-16 18:15:47.590538+0800 demo[48810:577013] ----2----after
使用runloop ?
運行runLoop
一次泊脐,阻塞當前線程以等待處理空幻。根據(jù)條件進行while循環(huán)
,達到條件后runloop
退出
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
__block BOOL isPerformNextStep = NO;
[self testLogOne];
for (NSInteger i = 0; i < 10; i ++) {
[self testLogTwo:^{
NSLog(@"----2----");
isPerformNextStep = YES;
}];
}
while (!isPerformNextStep) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[self testLogThree];
}
控制臺輸出:
2021-03-16 18:30:12.403732+0800 demo[54758:602699] ----1----
2021-03-16 18:30:12.407238+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.407371+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.407472+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.407554+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.407631+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.407726+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.407801+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.407909+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.408005+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.408137+0800 demo[54758:602699] ----2----
2021-03-16 18:30:12.408383+0800 demo[54758:602699] ----3----