一、A,B兩個類都繼承于UIView,B是A的subView禽车,兩者都重寫了touchBegan方法寇漫,點擊B時,兩個touchBegan方法的調(diào)用順序是什么殉摔?
分析:
1.如果touchBegan沒有調(diào)用super的touchBegan州胳,那么只會調(diào)用B的touchBegan
@implementation AView
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"%@ touchesBegan", self);
}
@end
@implementation BView
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"%@ touchesBegan", self);
}
@end
<BView: 0x7f9e0fc05c20; frame = (50 50; 50 50); layer = <CALayer: 0x600002b65b00>> touchesBegan
2.如果B的touchBegan調(diào)用了super的touchBegan,那么A的touchBegan也會調(diào)用
結(jié)論:如果自己實現(xiàn)touchBegan方法并且不調(diào)用super逸月,那么就阻斷了觸摸事件的繼續(xù)傳遞栓撞,所以superView的touchBegan不會調(diào)用,如果一直沒有阻斷傳遞碗硬,最終appDelegate會收到事件瓤湘,這個大家可以試下。此外恩尾,touchBegan方法的調(diào)用在hitTest:withEvent:之后弛说,hitTest:withEvent:是尋找觸摸事件目標(biāo)view的方法,touchBegan方法個人認為是已經(jīng)到了事件響應(yīng)階段翰意,所以不實現(xiàn)的話木人,就是傳遞到最外層的superResponder,要攔截事件響應(yīng)的話冀偶,自然是實現(xiàn)此方法醒第,至于需要調(diào)用super的touchBegan與否,則是看自己的業(yè)務(wù)需要了
關(guān)于touchBegan方法的解釋:
UIKit calls this method when a new touch is detected in a view or window. Many UIKit classes
override this method and use it to handle the corresponding touch events. The default
implementation of this method forwards the message up the responder chain. When creating
your own subclasses, call super to forward any events that you do not handle yourself. For
example,
[super touchesBegan:touches withEvent:event];
If you override this method without calling super (a common use pattern), you must also
override the other methods for handling touch events, even if your implementations do
nothing.
翻譯:
當(dāng)在視圖或窗口中檢測到新觸摸時进鸠,UIKit調(diào)用此方法稠曼。許多UIKit類重寫此方法并使用它來處
理相應(yīng)的觸摸事件。此方法的默認實現(xiàn)將消息轉(zhuǎn)發(fā)到響應(yīng)程序鏈堤如。創(chuàng)建自己的子類時蒲列,請調(diào)
用super來轉(zhuǎn)發(fā)您自己未處理的任何事件。例如搀罢,
[super touchesBegan:touch withEvent:event];
如果在不調(diào)用super(常用模式)的情況下覆蓋此方法蝗岖,則還必須覆蓋其他方法來處理觸摸
事件,即使您的實現(xiàn)不執(zhí)行任何操作也是如此榔至。
二抵赢、如果category中有一個與原類中同名但返回值不同的方法,會覆蓋原方法嗎?
結(jié)論:會覆蓋铅鲤,oc中是以selector其實就是一個string划提,比如:@selector(hitTest:withEvent:),selector是不包含返回值的信息的邢享,(PS:我要發(fā)消息給你鹏往,我只要把完整的消息告訴你就行了,我并不關(guān)心你的反應(yīng)/返回值)
三骇塘、gcd中伊履,如果在同步隊列a中向同步隊列b中添加任務(wù),會死鎖嗎款违?
結(jié)論:不會唐瀑,死鎖產(chǎn)生的條件是:“在某一個串行隊列中,同步的向這個隊列添加block”插爹。這里說不會的原因是哄辣,沒有間接地在b的向a又添加了任務(wù),這樣就形成了一個循環(huán)的等待狀態(tài)赠尾,類比于內(nèi)存的循環(huán)引用力穗,具體可以參考這個文章,我覺得寫的很多好:
https://blog.csdn.net/abc649395594/article/details/48017245
試驗:
dispatch_queue_t A = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t B = dispatch_queue_create("com.example.pass", DISPATCH_QUEUE_SERIAL);
dispatch_sync(A, ^{//sync1
NSLog(@"log 1, %@", [NSThread currentThread]);
dispatch_sync(B, ^{//sync2
NSLog(@"log 2, %@", NSThread.currentThread);
});
dispatch_sync(dispatch_get_main_queue(), ^{//sync3
NSLog(@"log 3, %@", NSThread.currentThread);
});
NSLog(@"log 4, %@", NSThread.currentThread);
});
NSLog(@"log 5, %@", NSThread.currentThread);
輸出:
log 1, <NSThread: 0x6000000b93c0>{number = 1, name = main}
log 2, <NSThread: 0x6000000b93c0>{number = 1, name = main}
為什么同是串行隊列萍虽,同步地向B隊列添加任務(wù)沒有導(dǎo)致死鎖睛廊,但是向主隊列中添加任務(wù)導(dǎo)致了死鎖?
知識點:隊列只是GCD給出的抽象數(shù)據(jù)結(jié)構(gòu)杉编。隊列是可以嵌套的超全,比如在A隊列(串行)添加一個任務(wù)a,在a這個任務(wù)中向B隊列(串行)添加任務(wù)b邓馒,在b這個任務(wù)中又向A隊列添加任務(wù)嘶朱,這就間接滿足了“在某一個串行隊列中,同步的向這個隊列添加block”光酣。
示例分析:我們向隊列A添加了任務(wù)a(包括任務(wù)1疏遏,sync2,sync3,任務(wù)4)救军,在sync2中向隊列B添加了任務(wù)2,在sync3中向主隊列中添加了任務(wù)3财异,sync與async的組合使用類似于“與”操作,多個sync嵌套其實還是直接向主隊列添加了任務(wù)(最外圍還是主隊列的任務(wù))唱遭,最終其實是:主隊列中任務(wù)3添加在了任務(wù)5之后(block中的任務(wù)是添加在隊列最后的)戳寸,但是任務(wù)5需要等待sync1返回才能執(zhí)行,而sync1需要等待block中的任務(wù)3執(zhí)行完后返回拷泽,相互等待=>死鎖
PS:(語拙疫鹊,自己理解的也不夠透徹)
四袖瞻、bitcode是什么?
http://blog.jonyfang.com/2017/06/21/introduction-to-bitcode/
這個文章我覺得寫的簡單易懂