今天在面試的時(shí)候遇到個(gè)新手傲醉,談到線程的時(shí)候,他說他經(jīng)常在子線程進(jìn)行頁面跳轉(zhuǎn)乌助,代碼類似如下這段,頁面A按了按鈕后跳轉(zhuǎn)頁面B陌知。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
BViewController *bV = [sb instantiateViewControllerWithIdentifier:@"vb"];
[self presentViewController:bV animated:NO completion:^{
}];
});
嗯他托,在子線程中使用presentViewController:animated:completion:
,并且成功進(jìn)行了頁面跳轉(zhuǎn)仆葡。
一般在子線程跳轉(zhuǎn)頁面代碼會(huì)出現(xiàn)頁面延遲加載赏参,這是因?yàn)樵谧泳€程結(jié)束后主線程實(shí)現(xiàn)了子線程函數(shù)棧的原因,所以第一次遇到這居然能成功及時(shí)跳轉(zhuǎn)還挺吃驚浙芙。經(jīng)驗(yàn)告訴我登刺,這段presentViewController:animated:completion:
雖然寫在子線程里,但是真正進(jìn)行頁面跳轉(zhuǎn)的應(yīng)該還是在主線程中嗡呼。
為了驗(yàn)證這個(gè)想法纸俭,給這段代碼加上日志。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"queue 1 currentThread:%@",[NSThread currentThread]);
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
BViewController *bV = [sb instantiateViewControllerWithIdentifier:@"vb"];
[self presentViewController:bV animated:NO completion:^{
NSLog(@"queue 2 currentThread %@", [NSThread currentThread]);
}];
});
不出所料南窗,得出的結(jié)果驗(yàn)證了我的想法揍很,確實(shí)進(jìn)入了主線程。
queue 1 currentThread:<NSThread: 0x60400026ff40>{number = 3, name = (null)}
queue 2 currentthread <NSThread: 0x600000066740>{number = 1, name = main}
那么為什么presentViewController:animated:completion:
可以在子線程中跳轉(zhuǎn)呢万伤?我用clang轉(zhuǎn)化成C/C++代碼窒悔,看看Runtime是不是可以暴露原因。
static void _I_ViewController_transitionView_(ViewController * self, SEL _cmd, id sender) {
dispatch_async(dispatch_get_global_queue(0, 0), ((void (*)())&__ViewController__transitionView__block_impl_1(
(void *)__ViewController__transitionView__block_func_1, &__ViewController__transitionView__block_desc_1_DATA, self, 570425344)));
}
emmmm.....完全看不出原因敌买,看來iOS底層隱藏了简珠。
iOS的模態(tài)試圖跳轉(zhuǎn)是通過消息傳遞的,所以猜測presentViewController:animated:completion:
的方式跳轉(zhuǎn)界面虹钮,可能在底層就是主線程執(zhí)行回調(diào)的聋庵。