- objc在向一個(gè)對(duì)象發(fā)送消息時(shí)機(jī)制是什么?
1藐唠、根據(jù)對(duì)象的 isa 指針找到類對(duì)象 id,在查詢類對(duì)象里面的 methodLists 方法函數(shù)列表,如果沒有在好到蜘澜,在沿著 superClass ,尋找父類,再在父類 methodLists 方法列表里面查詢响疚,最終找到 SEL ,根據(jù) id 和 SEL 確認(rèn) IMP(指針函數(shù)),再發(fā)送消息鄙信;
2、對(duì)象方法:(保存到類對(duì)象的方法列表) 忿晕,類方法:(保存到元類(Meta Class)中方法列表)
3装诡、每一個(gè)對(duì)象內(nèi)部都有一個(gè)isa指針,這個(gè)指針是指向它的真實(shí)類型践盼,根據(jù)這個(gè)指針就能知道將來調(diào)用哪個(gè)類的方法鸦采。
- unrecognized selector錯(cuò)誤如何處理?
當(dāng)發(fā)送消息的時(shí)候咕幻,我們會(huì)根據(jù)類里面的 methodLists 列表去查詢我們要?jiǎng)佑玫腟EL渔伯,當(dāng)查詢不到的時(shí)候,我們會(huì)一直沿著父類查詢谅河,當(dāng)最終查詢不到的時(shí)候我們會(huì)報(bào) unrecognized selector錯(cuò)誤咱旱。
此錯(cuò)誤常見于使用[self performSelector:@selector(unDefineSelector)]當(dāng)系統(tǒng)查詢不到方法的時(shí)候.
解決方案一: +(BOOL)resolveInstanceMethod:(SEL)sel 動(dòng)態(tài)解釋的方法來給我一次機(jī)會(huì)來添加确丢,調(diào)用不到的方法。
解決方案二:使用 -(id)forwardingTargetForSelector:(SEL)aSelector重定向的方法來告訴系統(tǒng)吐限,該調(diào)用什么方法鲜侥,一來保證不會(huì)崩潰。
其實(shí)都是單純的使程序不崩潰诸典,但是實(shí)際開發(fā)中除非封裝了極其強(qiáng)大的API描函,輕易不要去使用,那不然出錯(cuò)了都不不知道怎么fix
- 能否向編譯后得到的類中增加實(shí)例變量狐粱?能否向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量舀寓?為什么?
1肌蜻、不能向編譯后得到的類增加實(shí)例變量 .
編譯后的類已經(jīng)注冊(cè)在 runtime 中,類結(jié)構(gòu)體中的 objc_ivar_list 實(shí)例變量的鏈表和 instance_size 實(shí)例變量的內(nèi)存大小已經(jīng)確定互墓,runtime會(huì)調(diào)用 class_setvarlayout 或 class_setWeaklvarLayout 來處理strong weak 引用.所以不能向存在的類中添加實(shí)例變量。
2蒋搜、能向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量篡撵。
運(yùn)行時(shí)創(chuàng)建的類是可以添加實(shí)例變量,調(diào)用class_addIvar函數(shù). 但是的在調(diào)用 objc_allocateClassPair 之后豆挽,objc_registerClassPair 之前,原因同上.
- runtime如何實(shí)現(xiàn)weak變量的自動(dòng)置nil育谬?
runtime 對(duì)注冊(cè)的類, 會(huì)進(jìn)行布局帮哈,對(duì)于 weak 對(duì)象會(huì)放入一個(gè) hash 表中膛檀。 用 weak 指向的對(duì)象內(nèi)存地址作為 key,當(dāng)此對(duì)象的引用計(jì)數(shù)為0的時(shí)候會(huì) dealloc娘侍,假如 weak 指向的對(duì)象內(nèi)存地址是a咖刃,那么就會(huì)以a為鍵, 在這個(gè) weak 表中搜索私蕾,找到所有以a為鍵的 weak 對(duì)象僵缺,從而設(shè)置為 nil。
- 給類添加一個(gè)屬性后踩叭,在類結(jié)構(gòu)體里哪些元素會(huì)發(fā)生變化磕潮?
instance_size :實(shí)例的內(nèi)存大小容贝;objc_ivar_list *ivars:屬性列表
- runloop是來做什么的自脯?runloop和線程有什么關(guān)系?主線程默認(rèn)開啟了runloop么斤富?子線程呢膏潮?
runloop: 從字面意思看:運(yùn)行循環(huán)、跑圈满力,其實(shí)它內(nèi)部就是do-while循環(huán)焕参,在這個(gè)循環(huán)內(nèi)部不斷地處理各種任務(wù)(比如Source轻纪、Timer、Observer)事件叠纷。
runloop和線程的關(guān)系:一個(gè)線程對(duì)應(yīng)一個(gè)RunLoop刻帚,主線程的RunLoop默認(rèn)創(chuàng)建并啟動(dòng),子線程的RunLoop需手動(dòng)創(chuàng)建且手動(dòng)啟動(dòng)(調(diào)用run方法)涩嚣。
RunLoop只能選擇一個(gè)Mode啟動(dòng)崇众,如果當(dāng)前Mode中沒有任何Source(Sources0、Sources1)航厚、Timer顷歌,那么就直接退出RunLoop。
- runloop的mode是用來做什么的幔睬?有幾種mode眯漩?
model:是runloop里面的運(yùn)行模式,不同的模式下的runloop處理的事件和消息有一定的差別溪窒。系統(tǒng)默認(rèn)注冊(cè)了5個(gè)Mode:
(1)kCFRunLoopDefaultMode: App的默認(rèn) Mode坤塞,通常主線程是在這個(gè) Mode 下運(yùn)行的。
(2)UITrackingRunLoopMode: 界面跟蹤 Mode澈蚌,用于 ScrollView 追蹤觸摸滑動(dòng),保證界面滑動(dòng)時(shí)不受其他 Mode 影響灼狰。
(3)UIInitializationRunLoopMode: 在剛啟動(dòng) App 時(shí)第進(jìn)入的第一個(gè) Mode宛瞄,啟動(dòng)完成后就不再使用。
(4)GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode交胚,通常用不到份汗。
(5)kCFRunLoopCommonModes: 這是一個(gè)占位的 Mode,沒有實(shí)際作用蝴簇。
注意iOS 對(duì)以上5中model進(jìn)行了封裝 NSDefaultRunLoopMode杯活、NSRunLoopCommonModes
- 為什么把NSTimer對(duì)象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運(yùn)行循環(huán)以后,滑動(dòng)scrollview的時(shí)候NSTimer卻不動(dòng)了熬词?
nstime對(duì)象是在 NSDefaultRunLoopMode下面調(diào)用消息的旁钧,但是當(dāng)我們滑動(dòng)scrollview的時(shí)候,NSDefaultRunLoopMode模式就自動(dòng)切換到UITrackingRunLoopMode模式下面互拾,卻不可以繼續(xù)響應(yīng)nstime發(fā)送的消息歪今。所以如果想在滑動(dòng)scrollview的情況下面還調(diào)用nstime的消息,我們可以把nsrunloop的模式更改為NSRunLoopCommonModes.
-蘋果是如何實(shí)現(xiàn)Autorelease Pool的颜矿?
Autorelease Pool作用:緩存池寄猩,可以避免我們經(jīng)常寫relase的一種方式。其實(shí)就是延遲release骑疆,將創(chuàng)建的對(duì)象田篇,添加到最近的autoreleasePool中替废,等到autoreleasePool作用域結(jié)束的時(shí)候,會(huì)將里面所有的對(duì)象的引用計(jì)數(shù)器 - autorelease.
自動(dòng)釋放池也不是立馬就銷毀的泊柬,它會(huì)等資源閑置時(shí)再觸發(fā)舶担!
轉(zhuǎn)載出處
集團(tuán)部門要獨(dú)立出去了,干了8年iOS要試試跳槽了彬呻,有好坑歡迎介紹~