runtime怎么添加屬性宵蛀、方法等
? ivar表示成員變量
? class_addIvar
? class_addMethod
? class_addProperty
? class_addProtocol
? class_replaceProperty
是否可以把比較耗時(shí)的操作放在NSNotificationCenter中
? 首先必須明確通知在哪個(gè)線程中發(fā)出,那么處理接受到通知的方法也在這個(gè)線程中調(diào)用
? 如果在異步線程發(fā)的通知,那么可以執(zhí)行比較耗時(shí)的操作雹锣;
? 如果在主線程發(fā)的通知塑猖,那么就不可以執(zhí)行比較耗時(shí)的操作
runtime 如何實(shí)現(xiàn) weak 屬性
? 首先要搞清楚weak屬性的特點(diǎn)
weak策略表明該屬性定義了一種“非擁有關(guān)系” (nonowning relationship)疤孕。
為這種屬性設(shè)置新值時(shí),設(shè)置方法既不保留新值押逼,也不釋放舊值。此特質(zhì)同assign類似;
然而在屬性所指的對(duì)象遭到摧毀時(shí)惦界,屬性值也會(huì)清空(nil out)
? 那么runtime如何實(shí)現(xiàn)weak變量的自動(dòng)置nil挑格?
runtime對(duì)注冊(cè)的類,會(huì)進(jìn)行布局沾歪,會(huì)將 weak 對(duì)象放入一個(gè)hash表中漂彤。
用 weak 指向的對(duì)象內(nèi)存地址作為 key,當(dāng)此對(duì)象的引用計(jì)數(shù)為0的時(shí)候會(huì)調(diào)用對(duì)象的 dealloc 方法,
假設(shè)weak 指向的對(duì)象內(nèi)存地址是a显歧,那么就會(huì)以a為key仪或,在這個(gè) weak hash表中搜索,找到所有以a為key的 weak 對(duì)象士骤,從而設(shè)置為 nil范删。
weak屬性需要在dealloc中置nil么
? 在ARC環(huán)境無(wú)論是強(qiáng)指針還是弱指針都無(wú)需在 dealloc 設(shè)置為 nil , ARC 會(huì)自動(dòng)幫我們處理
? 即便是編譯器不幫我們做這些拷肌,weak也不需要在dealloc中置nil
? 在屬性所指的對(duì)象遭到摧毀時(shí)到旦,屬性值也會(huì)清空
模擬下weak的setter方法,大致如下
- (void)setObject:(NSObject *)object
{
objc_setAssociatedObject(self, "object", object, OBJC_ASSOCIATION_ASSIGN);
[object cyl_runAtDealloc:^{
_object = nil;
}];
}
一個(gè)Objective-C對(duì)象如何進(jìn)行內(nèi)存布局巨缘?(考慮有父類的情況)
? 所有父類的成員變量和自己的成員變量都會(huì)存放在該對(duì)象所對(duì)應(yīng)的存儲(chǔ)空間中
? 父類的方法和自己的方法都會(huì)緩存在類對(duì)象的方法緩存中添忘,類方法是緩存在元類對(duì)象中
? 每一個(gè)對(duì)象內(nèi)部都有一個(gè)isa指針,指向他的類對(duì)象,類對(duì)象中存放著本對(duì)象的如下信息
○ 對(duì)象方法列表
○ 成員變量的列表
○ 屬性列表
每個(gè)Objective-C 對(duì)象都有相同的結(jié)構(gòu),如下圖所示
Objective-C 對(duì)象的結(jié)構(gòu)圖
ISA指針
根類(NSObject)的實(shí)例變量
倒數(shù)第二層父類的實(shí)例變量
...
父類的實(shí)例變量
類的實(shí)例變量
? 根類對(duì)象就是NSObject若锁,它的super class指針指向nil
類對(duì)象既然稱為對(duì)象搁骑,那它也是一個(gè)實(shí)例。類對(duì)象中也有一個(gè)isa指針指向它的元類(meta class)又固,即類對(duì)象是元類的實(shí)例仲器。元類內(nèi)部存放的是類方法列表,根元類的isa指針指向自己仰冠,superclass指針指向NSObject類
[圖片上傳中乏冀。。洋只。(1)]
一個(gè)objc對(duì)象的isa的指針指向什么辆沦?有什么作用?
? 每一個(gè)對(duì)象內(nèi)部都有一個(gè)isa指針识虚,這個(gè)指針是指向它的真實(shí)類型
? 根據(jù)這個(gè)指針就能知道將來(lái)調(diào)用哪個(gè)類的方法
下面的代碼輸出什么肢扯?
@implementation Son : Father
- (id)init
{
self = [super init];
if (self) {
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
? 答案:都輸出Son
? 這個(gè)題目主要是考察關(guān)于objc中對(duì) self 和 super 的理解:
○ self 是類的隱藏參數(shù),指向當(dāng)前調(diào)用方法的這個(gè)類的實(shí)例舷礼。而 super 本質(zhì)是一個(gè)編譯器標(biāo)示符鹃彻,和 self 是指向的同一個(gè)消息接受者
○ 當(dāng)使用 self 調(diào)用方法時(shí),會(huì)從當(dāng)前類的方法列表中開(kāi)始找妻献,如果沒(méi)有蛛株,就從父類中再找;
○ 而當(dāng)使用 super時(shí)育拨,則從父類的方法列表中開(kāi)始找谨履。然后調(diào)用父類的這個(gè)方法
○ 調(diào)用[self class] 時(shí),會(huì)轉(zhuǎn)化成 objc_msgSend函數(shù)
id objc_msgSend(id self, SEL op, ...)
○ 調(diào)用 [super class]時(shí)熬丧,會(huì)轉(zhuǎn)化成 objc_msgSendSuper函數(shù)
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
○ 第一個(gè)參數(shù)是 objc_super 這樣一個(gè)結(jié)構(gòu)體笋粟,其定義如下
struct objc_super {
__unsafe_unretained id receiver;
__unsafe_unretained Class super_class;
};
○ 第一個(gè)成員是receiver, 類似于上面的 objc_msgSend函數(shù)第一個(gè)參數(shù)self
○ 第二個(gè)成員是記錄當(dāng)前類的父類是什么,告訴程序從父類中開(kāi)始找方法,找到方法后害捕,最后內(nèi)部是使用 objc_msgSend(objc_super->receiver, @selector(class))去調(diào)用绿淋, 此時(shí)已經(jīng)和[self class]調(diào)用相同了,故上述輸出結(jié)果仍然返回 Son
○ objc Runtime開(kāi)源代碼對(duì)- (Class)class方法的實(shí)現(xiàn)
-(Class)class {
return object_getClass(self);
}
runtime如何通過(guò)selector找到對(duì)應(yīng)的IMP地址尝盼?(分別考慮類方法和實(shí)例方法)
? 每一個(gè)類對(duì)象中都一個(gè)對(duì)象方法列表(對(duì)象方法緩存)
? 類方法列表是存放在類對(duì)象中isa指針指向的元類對(duì)象中(類方法緩存)
? 方法列表中每個(gè)方法結(jié)構(gòu)體中記錄著方法的名稱,方法實(shí)現(xiàn),以及參數(shù)類型吞滞,其實(shí)selector本質(zhì)就是方法名稱,通過(guò)這個(gè)方法名稱就可以在方法列表中找到對(duì)應(yīng)的方法實(shí)現(xiàn).
? 當(dāng)我們發(fā)送一個(gè)消息給一個(gè)NSObject對(duì)象時(shí),這條消息會(huì)在對(duì)象的類對(duì)象方法列表里查找
? 當(dāng)我們發(fā)送一個(gè)消息給一個(gè)類時(shí)盾沫,這條消息會(huì)在類的Meta Class對(duì)象的方法列表里查找
objc中的類方法和實(shí)例方法有什么本質(zhì)區(qū)別和聯(lián)系
? 類方法:
○ 類方法是屬于類對(duì)象的
○ 類方法只能通過(guò)類對(duì)象調(diào)用
○ 類方法中的self是類對(duì)象
○ 類方法可以調(diào)用其他的類方法
○ 類方法中不能訪問(wèn)成員變量
○ 類方法中不能直接調(diào)用對(duì)象方法
○ 類方法是存儲(chǔ)在元類對(duì)象的方法緩存中
? 實(shí)例方法:
○ 實(shí)例方法是屬于實(shí)例對(duì)象的
○ 實(shí)例方法只能通過(guò)實(shí)例對(duì)象調(diào)用
○ 實(shí)例方法中的self是實(shí)例對(duì)象
○ 實(shí)例方法中可以訪問(wèn)成員變量
○ 實(shí)例方法中直接調(diào)用實(shí)例方法
○ 實(shí)例方法中可以調(diào)用類方法(通過(guò)類名)
○ 實(shí)例方法是存放在類對(duì)象的方法緩存中
使用runtime Associate方法關(guān)聯(lián)的對(duì)象裁赠,需要在主對(duì)象dealloc的時(shí)候釋放么?
? 無(wú)論在MRC下還是ARC下均不需要
? 被關(guān)聯(lián)的對(duì)象在生命周期內(nèi)要比對(duì)象本身釋放的晚很多赴精,它們會(huì)在被 NSObject -dealloc 調(diào)用的object_dispose()方法中釋放
? 補(bǔ)充:對(duì)象的內(nèi)存銷毀時(shí)間表佩捞,分四個(gè)步驟
1.調(diào)用-release :引用計(jì)數(shù)變?yōu)榱?/p>
- 對(duì)象正在被銷毀,生命周期即將結(jié)束.
- 不能再有新的 __weak 弱引用蕾哟,否則將指向 nil.
- 調(diào)用 [self dealloc]
- 父類調(diào)用-dealloc
- 繼承關(guān)系中最直接繼承的父類再調(diào)用 -dealloc
- 如果是MRC 代碼 則會(huì)手動(dòng)釋放實(shí)例變量們(iVars)
- 繼承關(guān)系中每一層的父類 都再調(diào)用 -dealloc
- NSObject 調(diào) -dealloc
- 只做一件事:調(diào)用Objective-C runtime 中的 object_dispose() 方法
- 調(diào)用object_dispose()
- 為 C++ 的實(shí)例變量們(iVars)調(diào)用destructors
- 為 ARC 狀態(tài)下的 實(shí)例變量們(iVars) 調(diào)用 -release
- 解除所有使用runtime Associate方法關(guān)聯(lián)的對(duì)象
- 解除所有 __weak 引用
- 調(diào)用free()
_objc_msgForward函數(shù)是做什么的一忱?直接調(diào)用它將會(huì)發(fā)生什么?
? _objc_msgForward是IMP類型渐苏,用于消息轉(zhuǎn)發(fā)的:當(dāng)向一個(gè)對(duì)象發(fā)送一條消息掀潮,但它并沒(méi)有實(shí)現(xiàn)的時(shí)候,_objc_msgForward會(huì)嘗試做消息轉(zhuǎn)發(fā)
? 直接調(diào)用_objc_msgForward是非常危險(xiǎn)的事琼富,這是把雙刃刀,如果用不好會(huì)直接導(dǎo)致程序Crash庄新,但是如果用得好鞠眉,能做很多非常酷的事
? JSPatch就是直接調(diào)用_objc_msgForward來(lái)實(shí)現(xiàn)其核心功能的
? 詳細(xì)解說(shuō)參見(jiàn)這里的第一個(gè)問(wèn)題解答
能否向編譯后得到的類中增加實(shí)例變量择诈?能否向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量械蹋?為什么?
? 不能向編譯后得到的類中增加實(shí)例變量羞芍;
? 能向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量哗戈;
? 分析如下:
○ 因?yàn)榫幾g后的類已經(jīng)注冊(cè)在runtime中,類結(jié)構(gòu)體中的objc_ivar_list 實(shí)例變量的鏈表和instance_size實(shí)例變量的內(nèi)存大小已經(jīng)確定荷科,同時(shí)runtime 會(huì)調(diào)用class_setIvarLayout 或 class_setWeakIvarLayout來(lái)處理strong weak引用唯咬,所以不能向存在的類中添加實(shí)例變量
○ 運(yùn)行時(shí)創(chuàng)建的類是可以添加實(shí)例變量,調(diào)用 class_addIvar函數(shù)畏浆,但是得在調(diào)用objc_allocateClassPair之后胆胰,objc_registerClassPair之前,原因同上刻获。
runloop和線程有什么關(guān)系蜀涨?
? 每條線程都有唯一的一個(gè)RunLoop對(duì)象與之對(duì)應(yīng)的
? 主線程的RunLoop是自動(dòng)創(chuàng)建并啟動(dòng)
? 子線程的RunLoop需要手動(dòng)創(chuàng)建
? 子線程的RunLoop創(chuàng)建步驟如下:
○ 在子線程中調(diào)用[NSRunLoop currentRunLoop]創(chuàng)建RunLoop對(duì)象(懶加載,只創(chuàng)建一次)
○ 獲得RunLoop對(duì)象后要調(diào)用run方法來(lái)啟動(dòng)一個(gè)運(yùn)行循環(huán)
啟動(dòng)RunLoop
[[NSRunLoop currentRunLoop] run];
○ RunLoop的其他啟動(dòng)方法
第一個(gè)參數(shù):指定運(yùn)行模式
第二個(gè)參數(shù):指定RunLoop的過(guò)期時(shí)間,即:到了這個(gè)時(shí)間后RunLoop就失效了
[[NSRunLoop currentRunLoop] runMode:kCFRunLoopDefaultMode beforeDate:[NSDate distantFuture]];
runloop的mode作用是什么厚柳?
? 用來(lái)控制一些特殊操作只能在指定模式下運(yùn)行氧枣,一般可以通過(guò)指定操作的運(yùn)行mode來(lái)控制執(zhí)行時(shí)機(jī),以提高用戶體驗(yàn)
? 系統(tǒng)默認(rèn)注冊(cè)了5個(gè)Mode
○ kCFRunLoopDefaultMode:App的默認(rèn)Mode别垮,通常主線程是在這個(gè)Mode下運(yùn)行便监,對(duì)應(yīng)OC中的:NSDefaultRunLoopMode
○ UITrackingRunLoopMode:界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動(dòng)宰闰,保證界面滑動(dòng)時(shí)不受其他Mode影響
○ kCFRunLoopCommonModes:這是一個(gè)標(biāo)記Mode茬贵,不是一種真正的Mode,事件可以運(yùn)行在所有標(biāo)有common modes標(biāo)記的模式中移袍,對(duì)應(yīng)OC中的NSRunLoopCommonModes解藻,帶有common modes標(biāo)記的模式有:UITrackingRunLoopMode和kCFRunLoopDefaultMode
○ UIInitializationRunLoopMode:在啟動(dòng) App時(shí)進(jìn)入的第一個(gè) Mode,啟動(dòng)完成后就不再使用
○ GSEventReceiveRunLoopMode:接受系統(tǒng)事件的內(nèi)部Mode葡盗,通常用不到
以+scheduledTimerWithTimeInterval...的方式觸發(fā)的timer螟左,在滑動(dòng)頁(yè)面上的列表時(shí),timer會(huì)暫定回調(diào)觅够,為什么胶背?如何解決?
? 這里強(qiáng)調(diào)一點(diǎn):在主線程中以+scheduledTimerWithTimeInterval...的方式觸發(fā)的timer默認(rèn)是運(yùn)行在NSDefaultRunLoopMode模式下的喘先,當(dāng)滑動(dòng)頁(yè)面上的列表時(shí)钳吟,進(jìn)入了UITrackingRunLoopMode模式,這時(shí)候timer就會(huì)停止
? 可以修改timer的運(yùn)行模式為NSRunLoopCommonModes窘拯,這樣定時(shí)器就可以一直運(yùn)行了
? 以下是我的筆記補(bǔ)充:
○ 在子線程中通過(guò)scheduledTimerWithTimeInterval:...方法來(lái)構(gòu)建NSTimer
§ 方法內(nèi)部已經(jīng)創(chuàng)建NSTimer對(duì)象红且,并加入到RunLoop中,運(yùn)行模式為NSDefaultRunLoopMode
§ 由于Mode有timer對(duì)象涤姊,所以RunLoop就開(kāi)始監(jiān)聽(tīng)定時(shí)器事件了暇番,從而開(kāi)始進(jìn)入運(yùn)行循環(huán)
§ 這個(gè)方法僅僅是創(chuàng)建RunLoop對(duì)象,并不會(huì)主動(dòng)啟動(dòng)RunLoop思喊,需要再調(diào)用run方法來(lái)啟動(dòng)
○ 如果在主線程中通過(guò)scheduledTimerWithTimeInterval:...方法來(lái)構(gòu)建NSTimer壁酬,就不需要主動(dòng)啟動(dòng)RunLoop對(duì)象,因?yàn)橹骶€程的RunLoop對(duì)象在程序運(yùn)行起來(lái)就已經(jīng)被啟動(dòng)了
userInfo參數(shù):用來(lái)給NSTimer的userInfo屬性賦值恨课,userInfo是只讀的舆乔,只能在構(gòu)建NSTimer對(duì)象時(shí)賦值
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run:) userInfo:@"ya了個(gè)hoo" repeats:YES];
scheduledTimer...方法創(chuàng)建出來(lái)NSTimer雖然已經(jīng)指定了默認(rèn)模式,但是【允許你修改模式】
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
【僅在子線程】需要手動(dòng)啟動(dòng)RunLoop對(duì)象庄呈,進(jìn)入運(yùn)行循環(huán)
[[NSRunLoop currentRunLoop] run];
猜想runloop內(nèi)部是如何實(shí)現(xiàn)的蜕煌?
? 從字面意思看:運(yùn)行循環(huán)、跑圈诬留;
? 本質(zhì):內(nèi)部就是do-while循環(huán)斜纪,在這個(gè)循環(huán)內(nèi)部不斷地處理各種事件(任務(wù))贫母,比如:Source、Timer盒刚、Observer腺劣;
? 每條線程都有唯一一個(gè)RunLoop對(duì)象與之對(duì)應(yīng),主線程的RunLoop默認(rèn)已經(jīng)啟動(dòng)因块,子線程的RunLoop需要手動(dòng)啟動(dòng)橘原;
? 每次RunLoop啟動(dòng)時(shí),只能指定其中一個(gè) Mode涡上,這個(gè)Mode被稱作 CurrentMode趾断,如果需要切換Mode,只能退出Loop吩愧,再重新指定一個(gè)Mode進(jìn)入芋酌,這樣做主要是為了隔離不同Mode中的Source、Timer雁佳、Observer脐帝,讓其互不影響;
? 附上RunLoop的運(yùn)行圖
[圖片上傳中糖权。堵腹。。(2)]
不手動(dòng)指定autoreleasepool的前提下星澳,一個(gè)autorealese對(duì)象在什么時(shí)刻釋放疚顷?(比如在一個(gè)vc的viewDidLoad中創(chuàng)建)
? 分兩種情況:手動(dòng)干預(yù)釋放時(shí)機(jī)、系統(tǒng)自動(dòng)去釋放
○ 手動(dòng)干預(yù)釋放時(shí)機(jī):指定autoreleasepool就是所謂的:當(dāng)前作用域大括號(hào)結(jié)束時(shí)就立即釋放
○ 系統(tǒng)自動(dòng)去釋放:不手動(dòng)指定autoreleasepool禁偎,Autorelease對(duì)象會(huì)在當(dāng)前的 runloop 迭代結(jié)束時(shí)釋放荡含,下面詳細(xì)說(shuō)明釋放時(shí)機(jī)
§ RunLoop中的三個(gè)狀態(tài)會(huì)處理自動(dòng)釋放池,通過(guò)打印代碼發(fā)現(xiàn)有兩個(gè)Observer監(jiān)聽(tīng)到狀態(tài)值為:1和160(32+128)
□ kCFRunLoopEntry(1) 第一次進(jìn)入會(huì)創(chuàng)建一個(gè)自動(dòng)釋放池
□ kCFRunLoopBeforeWaiting(32) 進(jìn)入休眠狀態(tài)前先銷毀自動(dòng)釋放池届垫,再創(chuàng)建一個(gè)新的自動(dòng)釋放池
□ kCFRunLoopExit(128) 退出RunLoop時(shí)銷毀最后一次創(chuàng)建的自動(dòng)釋放池
? 如果在一個(gè)vc的viewDidLoad中創(chuàng)建一個(gè)Autorelease對(duì)象,那么該對(duì)象會(huì)在 viewDidAppear 方法執(zhí)行前就被銷毀了(是這樣的嗎全释?装处??)
蘋果是如何實(shí)現(xiàn)autoreleasepool的浸船?
? autoreleasepool以一個(gè)隊(duì)列數(shù)組的形式實(shí)現(xiàn),主要通過(guò)下列三個(gè)函數(shù)完成.
objc_autoreleasepoolPush
objc_autoreleasepoolPop
objc_aurorelease
? 看函數(shù)名就可以知道妄迁,對(duì)autorelease分別執(zhí)行push,和pop操作李命。銷毀對(duì)象時(shí)執(zhí)行release操作
GCD的隊(duì)列(dispatch_queue_t)分哪兩種類型登淘?背后的線程模型是什么樣的?
? 串行隊(duì)列
? 并行隊(duì)列
? dispatch_global_queue();是全局并發(fā)隊(duì)列
? dispatch_main_queue();是一種特殊串行隊(duì)列
? 背后的線程模型:自定義隊(duì)列 dispatch_queue_t queue; 可以自定義是并行:DISPATCH_QUEUE_CONCURRENT 或者 串行DISPATCH_QUEUE_SERIAL
蘋果為什么要廢棄dispatch_get_current_queue封字?
? 容易誤用造成死鎖
如何用GCD同步若干個(gè)異步調(diào)用黔州?(如根據(jù)若干個(gè)url異步加載多張圖片耍鬓,然后在都下載完成后合成一張整圖)
? 必須是并發(fā)隊(duì)列才起作用
? 需求分析
○ 首先,分別異步執(zhí)行2個(gè)耗時(shí)的操作
○ 其次流妻,等2個(gè)異步操作都執(zhí)行完畢后牲蜀,再回到主線程執(zhí)行一些操作
? 使用隊(duì)列組實(shí)現(xiàn)上面的需求
創(chuàng)建隊(duì)列組
dispatch_group_t group = dispatch_group_create();
獲取全局并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
往隊(duì)列組中添加耗時(shí)操作
dispatch_group_async(group, queue, ^{
執(zhí)行耗時(shí)的異步操作1
});
往隊(duì)列組中添加耗時(shí)操作
dispatch_group_async(group, queue, ^{
執(zhí)行耗時(shí)的異步操作2
});
當(dāng)并發(fā)隊(duì)列組中的任務(wù)執(zhí)行完畢后才會(huì)執(zhí)行這里的代碼
dispatch_group_notify(group, queue, ^{
如果這里還有基于上面兩個(gè)任務(wù)的結(jié)果繼續(xù)執(zhí)行一些代碼,建議還是放到子線程中绅这,等代碼執(zhí)行完畢后在回到主線程
回到主線程
dispatch_async(group, dispatch_get_main_queue(), ^{
執(zhí)行相關(guān)代碼...
});
});
dispatch_barrier_async的作用是什么涣达?
? 函數(shù)定義
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
? 必須是并發(fā)隊(duì)列,要是串行隊(duì)列证薇,這個(gè)函數(shù)就沒(méi)啥意義了
? 注意:這個(gè)函數(shù)的第一個(gè)參數(shù)queue不能是全局的并發(fā)隊(duì)列
? 作用:在它前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行度苔,在它后面的任務(wù)等它執(zhí)行完成后才會(huì)執(zhí)
? 示例代碼
-(void)barrier
{
dispatch_queue_t queue = dispatch_queue_create("12342234", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"----1-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----2-----%@", [NSThread currentThread]);
});
在它前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,在它后面的任務(wù)等它執(zhí)行完成后才會(huì)執(zhí)行
dispatch_barrier_async(queue, ^{
NSLog(@"----barrier-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----3-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----4-----%@", [NSThread currentThread]);
});
}
以下代碼運(yùn)行結(jié)果如何浑度?
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
}
? 答案:主線程死鎖