Runtime
<a href="#26">1. objc在向一個對象發(fā)送消息時,發(fā)生了什么?</a>
<a href="#27">2. 什么時候會報unrecognized selector錯誤?iOS有哪些機(jī)制來避免走到這一步?</a>
<a href="#28">3. 能否向編譯后得到的類中增加實(shí)例變量?能否向運(yùn)行時創(chuàng)建的類中添加實(shí)例變量?為什么?</a>
<a href="#29">4. runtime如何實(shí)現(xiàn)weak變量的自動置nil?</a>
<a href="#30">5. 給類添加一個屬性后,在類結(jié)構(gòu)體里哪些元素會發(fā)生變化?</a>
RunLoop
<a href="#31">1. runloop是來做什么的?runloop和線程有什么關(guān)系?主線程默認(rèn)開啟了runloop么?子線程呢?</a>
<a href="#32">2. runloop的mode是用來做什么的?有幾種mode?</a>
<a href="#33">3. 為什么把NSTimer對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運(yùn)行循環(huán)以后,滑動scrollview的時候NSTimer卻不動了?</a>
<a href="#34">4. 蘋果是如何實(shí)現(xiàn)Autorelease Pool的?</a>
類結(jié)構(gòu)
<a href="#35">1. isa指針?(對象的isa,類對象的isa,元類的isa都要說)</a>
<a href="#36">2. 類方法和實(shí)例方法有什么區(qū)別?</a>
<a href="#37">3. 介紹一下分類,能用分類做什么?內(nèi)部是如何實(shí)現(xiàn)的?它為什么會覆蓋掉原來的方法?</a>
<a href="#38">4. 運(yùn)行時能增加成員變量么?能增加屬性么?如果能,如何增加?如果不能,為什么?</a>
<a href="#39">5. objc中向一個nil對象發(fā)送消息將會發(fā)生什么?(返回值是對象,是標(biāo)量,結(jié)構(gòu)體)</a>
高級
<a href="#40">1. UITableview的優(yōu)化方法(緩存高度,異步繪制,減少層級,hide,避免離屏渲染)</a>
<a href="#41">2. 有沒有用過運(yùn)行時,用它都能做什么?(交換方法,創(chuàng)建類,給新創(chuàng)建的類增加方法,改變isa指針)</a>
<a href="#42">3. 看過哪些第三方框架的源碼?都是如何實(shí)現(xiàn)的?(如果沒有,問一下多圖下載的設(shè)計)</a>
<a href="#43">4. SDWebImage的緩存策略?</a>
<a href="#44">5. AFN為什么添加一條常駐線程?</a>
<a href="#45">6. KVO的使用?實(shí)現(xiàn)原理?(為什么要創(chuàng)建子類來實(shí)現(xiàn))</a>
<a href="#46">7. KVC的使用?實(shí)現(xiàn)原理?(KVC拿到key以后,是如何賦值的?知不知道集合操作符,能不能訪問私有屬性,能不能直接訪問_ivar)</a>
項目
<a href="#47">1. 有已經(jīng)上線的項目么?</a>
<a href="#48">2. 項目里哪個部分是你完成的?(找一個亮點(diǎn)問一下如何實(shí)現(xiàn)的)</a>
<a href="#49">3. 開發(fā)過程中遇到過什么困難,是如何解決的?</a>
學(xué)習(xí)
<a href="#50">1. 遇到一個問題完全不能理解的時候,是如何幫助自己理解的?舉個例子?</a>
<a href="#51">2. 有看書的習(xí)慣么?最近看的一本是什么書?有什么心得?</a>
<a href="#52">3. 有沒有使用一些筆記軟件?會在多平臺同步以及多渠道采集么?(如果沒有,問一下是如何復(fù)習(xí)知識的)</a>
<a href="#53">4. 有沒有使用清單類,日歷類的軟件?(如果沒有,問一下是如何安排,計劃任務(wù)的)</a>
<a href="#54">5. 平??床┛兔??有沒有自己寫過?(如果寫,有哪些收獲?如果沒有寫,問一下不寫的原因)</a>
答案區(qū)
Runtime
<a id="26">1. objc在向一個對象發(fā)送消息時,發(fā)生了什么? </a>
這片文章講的比較詳細(xì)-> 理解Objective-C中的消息發(fā)送
<a id="27">2. 什么時候會報unrecognized selector錯誤?iOS有哪些機(jī)制來避免走到這一步?</a>
是該object中沒有定義這個函數(shù)或者該對象也就被釋放的時候就會報unrecognized selector錯誤
怎樣避免
1.使用[id respondsToSelector:]進(jìn)行判斷
2.Method resolution
objc運(yùn)行時會調(diào)用+resolveInstanceMethod:或者 +resolveClassMethod:,讓你有機(jī)會提供一個函數(shù)實(shí)現(xiàn)。如果你添加了函數(shù),那運(yùn)行時系統(tǒng)就會重新啟動一次消息發(fā)送的過程,否則 ,運(yùn)行時就會移到下一步,消息轉(zhuǎn)發(fā)(Message Forwarding)。
返回Nil和self,去調(diào)用第三步methodSignatureForSelector和forwarInvocation;返回receiver,如果receiver有響應(yīng)就直接處理,如果沒有就去對應(yīng)的對象內(nèi)去調(diào)用第三步;調(diào)用子類的函數(shù),子類沒有進(jìn)行這幾個方法的重載,在父類處理時返回子類,會死循環(huán)。
3.Fast forwarding
如果目標(biāo)對象實(shí)現(xiàn)了-forwardingTargetForSelector:,Runtime 這時就會調(diào)用這個方法,給你把這個消息轉(zhuǎn)發(fā)給其他對象的機(jī)會。 只要這個方法返回的不是nil和self,整個消息發(fā)送的過程就會被重啟,當(dāng)然發(fā)送的對象會變成你返回的那個對象。否則,就會繼續(xù)Normal Fowarding。 這里叫Fast,只是為了區(qū)別下一步的轉(zhuǎn)發(fā)機(jī)制。因?yàn)檫@一步不會創(chuàng)建任何新的對象,但下一步轉(zhuǎn)發(fā)會創(chuàng)建一個NSInvocation對象,所以相對更快點(diǎn)。
4.Normal forwarding
這一步是Runtime最后一次給你挽救的機(jī)會。首先它會發(fā)送-methodSignatureForSelector:消息獲得函數(shù)的參數(shù)和返回值類型。如果-methodSignatureForSelector:返回nil,Runtime則會發(fā)出-doesNotRecognizeSelector:消息,程序這時也就掛掉了。如果返回了一個函數(shù)簽名,Runtime就會創(chuàng)建一個NSInvocation對象并發(fā)送-forwardInvocation:消息給目標(biāo)對象。
<a id="28">3. 能否向編譯后得到的類中增加實(shí)例變量?能否向運(yùn)行時創(chuàng)建的類中添加實(shí)例變量?為什么?</a>
不能向編譯后得到的類中增加實(shí)例變量;
能向運(yùn)行時創(chuàng)建的類中添加實(shí)例變量;
原因如下:
因?yàn)榫幾g后的類已經(jīng)注冊在 runtime 中,類結(jié)構(gòu)體中的 objc_ivar_list 實(shí)例變量的鏈表 和 instance_size 實(shí)例變量的內(nèi)存大小已經(jīng)確定,同時runtime 會調(diào)用 class_setIvarLayout 或 class_setWeakIvarLayout 來處理 strong weak 引用。所以不能向存在的類中添加實(shí)例變量;
運(yùn)行時創(chuàng)建的類是可以添加實(shí)例變量,調(diào)用 class_addIvar 函數(shù)。但是得在調(diào)用 objc_allocateClassPair 之后,objc_registerClassPair 之前,原因同上。
<a id="29">4. runtime如何實(shí)現(xiàn)weak變量的自動置nil?</a>
一個普遍的解釋是:runtime對注冊的類會進(jìn)行布局,對于weak修飾的對象會放入一個hash表中。用weak指向的對象內(nèi)存地址作為key,當(dāng)此對象的引用計數(shù)為0的時候會dealloc,假如weak指向的對象內(nèi)存地址是a,那么就會以a為鍵在這個weak表中搜索,找到所有以a為鍵的weak對象,從而設(shè)置為nil。
<a id="30">5. 給類添加一個屬性后,在類結(jié)構(gòu)體里哪些元素會發(fā)生變化?</a>
待補(bǔ)充...
RunLoop
<a id="31">1. runloop是來做什么的?runloop和線程有什么關(guān)系?主線程默認(rèn)開啟了runloop么?子線程呢?</a>
Run Loop是一讓線程能隨時處理事件但不退出的機(jī)制。RunLoop 實(shí)際上是一個對象,這個對象管理了其需要處理的事件和消息,并提供了一個入口函數(shù)來執(zhí)行Event Loop 的邏輯。線程執(zhí)行了這個函數(shù)后,就會一直處于這個函數(shù)內(nèi)部 “接受消息->等待->處理” 的循環(huán)中,直到這個循環(huán)結(jié)束(比如傳入 quit 的消息),函數(shù)返回。讓線程在沒有處理消息時休眠以避免資源占用、在有消息到來時立刻被喚醒。
主線程的RunLoop是自動創(chuàng)建并啟動
子線程的RunLoop需要手動創(chuàng)建
<a id="32">2. runloop的mode是用來做什么的?有幾種mode?</a>
用來控制一些特殊操作只能在指定模式下運(yùn)行,一般可以通過指定操作的運(yùn)行mode 來控制執(zhí)行時機(jī),以提高用戶體驗(yàn)
系統(tǒng)默認(rèn)注冊了5個Mode:
(1)kCFRunLoopDefaultMode: App的默認(rèn) Mode,通常主線程是在這個 Mode 下運(yùn)行的。
(2)UITrackingRunLoopMode: 界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他 Mode 影響。
(3)UIInitializationRunLoopMode: 在剛啟動 App 時第進(jìn)入的第一個 Mode,啟動完成后就不再使用。
(4)GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode,通常用不到。
(5)kCFRunLoopCommonModes: 這是一個占位的 Mode,沒有實(shí)際作用。
<a id="33">3. 為什么把NSTimer對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運(yùn)行循環(huán)以后,滑動scrollview的時候NSTimer卻不動了?</a>
ScrollView滾動過程中會因?yàn)閙ode的切換,而導(dǎo)致NSTimer將不再被調(diào)度。當(dāng)我們滾動的時候,也希望不調(diào)度,那就應(yīng)該使用默認(rèn)模式。但是,如果希望在滾動時,定時器也要回調(diào),那就應(yīng)該使用common mode。
<a id="34">4. 蘋果是如何實(shí)現(xiàn)Autorelease Pool的?</a>
詳情查看此篇文章->黑幕背后的Autorelease
類結(jié)構(gòu)
<a id="35">1. isa指針?(對象的isa,類對象的isa,元類的isa都要說)</a>
isa指針是一個Class 類型的指針. 每個實(shí)例對象有個isa的指針,他指向?qū)ο蟮念?,而Class里也有個isa的指針, 指向meteClass(元類)。元類保存了類方法的列表。當(dāng)類方法被調(diào)用時,先會從本身查找類方法的實(shí)現(xiàn),如果沒有,元類會向他父類查找該方法。同時注意的是:元類(meteClass)也是類,它也是對象。元類也有isa指針,它的isa指針最終指向的是一個根元類(root meteClass).根元類的isa指針指向本身,這樣形成了一個封閉的內(nèi)循環(huán)。
<a id="36">2. 類方法和實(shí)例方法有什么區(qū)別?</a>
Objective-C里面既有實(shí)例方法也類方法。類方法(Class Method) 有時被稱為工廠方法(Factory Method)或者方便方法(Convenience method)。工廠方法的稱謂明顯和一般意義上的工廠方法不同,從本質(zhì)上來說,類方法可以獨(dú)立于對象而執(zhí)行,所以在其他的語言里面類方法有的時候被稱為靜態(tài)方法。
注意點(diǎn)一:類方法
1,類方法可以調(diào)用類方法。
2,類方法不可以調(diào)用實(shí)例方法,但是類方法可以通過創(chuàng)建對象來訪問實(shí)例方法。
3,類方法不可以使用實(shí)例變量。類方法可以使用self,因?yàn)閟elf不是實(shí)例變量。4,類方法作為消息,可以被發(fā)送到類或者對象里面去(實(shí)際上,就是可以通過類或者對象調(diào)用類方法的意思)。
注意點(diǎn)二:self的規(guī)則大家需要記住下面的規(guī)則:
1,實(shí)例方法里面的self,是對象的首地址。
2,類方法里面的self,是Class.盡管在同一個類里面的使用self,但是self卻有著不同的解讀。在類方法里面的self,可以翻譯成class self;在實(shí)例方法里面的self,應(yīng)該被翻譯成為object self。在類方法里面的self和實(shí)例方法里面的self有著本質(zhì)上的不同,盡管他們的名字都叫self。
<a id="37">3. 介紹一下分類,能用分類做什么?內(nèi)部是如何實(shí)現(xiàn)的?它為什么會覆蓋掉原來的方法?</a>
作用:可以在不修改原來類的基礎(chǔ)上,為一個類擴(kuò)展方法。
CocoaFramework有很多是用Category實(shí)現(xiàn)的,重寫之后,會導(dǎo)致在Runtime的時候,只有一個方法會被執(zhí)行,而哪個會被執(zhí)行是undefined。
<a id="38">4. 運(yùn)行時能增加成員變量么?能增加屬性么?如果能,如何增加?如果不能,為什么?</a>
看這個解釋-><a href="#28"> 能否向編譯后得到的類中增加實(shí)例變量?能否向運(yùn)行時創(chuàng)建的類中添加實(shí)例變量?為什么?</a>
<a id="39">5. objc中向一個nil對象發(fā)送消息將會發(fā)生什么?(返回值是對象,是標(biāo)量,結(jié)構(gòu)體)</a>
在 Objective-C 中向 nil 發(fā)送消息是完全有效的——只是在運(yùn)行時不會有任何作用
詳情看此篇文章->問題[※※]:objc中向一個nil對象發(fā)送消息將會發(fā)生什么?
高級
<a id="40">1. UITableview的優(yōu)化方法(緩存高度,異步繪制,減少層級,hide,避免離屏渲染)</a>
優(yōu)化的方式就那幾種,百度一搜一大把,下面這個文章說的比較全面了 參考此篇文章即可-> iOS中UITableView性能優(yōu)化
<a id="41">2. 有沒有用過運(yùn)行時,用它都能做什么?(交換方法,創(chuàng)建類,給新創(chuàng)建的類增加方法,改變isa指針)</a>
這個同上百度一大把 為了方便推薦個鏈接吧->iOS~runtime理解
<a id="42">3. 看過哪些第三方框架的源碼?都是如何實(shí)現(xiàn)的?(如果沒有,問一下多圖下載的設(shè)計)</a>
比較好的第三方源碼個人推薦YYKit
然后多圖下載的話參考這篇文章->iOS開發(fā)網(wǎng)絡(luò)多線程之多圖下載
然后比較好的第三方如SDWebImage、YYWebImage都支持多圖下載
<a id="43">4. SDWebImage的緩存策略?</a>
1.緩存策略-SDWebImageOptions
默認(rèn)是開啟了硬盤\內(nèi)存緩存的
- SDWebImageRetryFailed 下載失敗了會再次嘗試下載
- SDWebImageLowPriority 當(dāng)UIScrollView等正在滾動時,延遲下載圖片(放置scrollView滾動卡)
- SDWebImageCacheMemoryOnly 只緩存到內(nèi)存中,不緩存到硬盤上
- SDWebImageProgressiveDownload 圖片會一點(diǎn)一點(diǎn)慢慢顯示出來(就像瀏覽器顯示網(wǎng)頁上的圖片一樣)
- SDWebImageRefreshCached 將硬盤緩存交給系統(tǒng)自帶的NSURLCache去處理,當(dāng)同一個URL對應(yīng)的圖片經(jīng)常更改時可以用這種策略
<a id="44">5. AFN為什么添加一條常駐線程?</a>
正常的線程任務(wù)完成后,線程就為finished狀態(tài),只能銷毀再創(chuàng)建。如果想讓一個線程常駐線程,實(shí)時的響應(yīng)調(diào)度,則可以利用runloop高效的分配任務(wù)。
- (void)viewDidLoad {
[super viewDidLoad];
//創(chuàng)建一個線程
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(createRunloopByNormal) object:nil] ;
//
// self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(createRunloopByCFObserver) object:nil] ;
//
// self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(createRunloopByCFTimer) object:nil] ;
//
// self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(createRunloopByCFSource) object:nil] ;
[self.thread start];
}
/**
* 一般創(chuàng)建runloop的方法。結(jié)果:成功
*/
- (void)createRunloopByNormal{
@autoreleasepool {
//添加port源,保證runloop正常輪詢,不會創(chuàng)建后直接退出。
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
//開啟runloop
[[NSRunLoop currentRunLoop] run];
}
}
<a id="45">6. KVO的使用?實(shí)現(xiàn)原理?(為什么要創(chuàng)建子類來實(shí)現(xiàn))</a>
當(dāng)觀察某對象A時,KVO機(jī)制動態(tài)創(chuàng)建一個對象A當(dāng)前類的子類,并為這個新的子類重寫了被觀察屬性keyPath的setter 方法。setter 方法隨后負(fù)責(zé)通知觀察對象屬性的改變狀況。
KVO 的實(shí)現(xiàn)依賴于 Objective-C 強(qiáng)大的 Runtime
來來來 看這里->iOS開發(fā)-- KVO的實(shí)現(xiàn)原理與具體應(yīng)用
<a id="46">7. KVC的使用?實(shí)現(xiàn)原理?(KVC拿到key以后,是如何賦值的?知不知道集合操作符,能不能訪問私有屬性,能不能直接訪問_ivar)</a>
這里面解釋的很清楚 看這里就行->iOS底層-KVC使用實(shí)踐以及實(shí)現(xiàn)原理
項目
<a id="47">1. 有已經(jīng)上線的項目么?</a>
這個就不說了 如果沒有上線的項目的話那還面試個卵
<a id="48">2. 項目里哪個部分是你完成的?(找一個亮點(diǎn)問一下如何實(shí)現(xiàn)的)</a>
這個看自己實(shí)際情況 。
我本人呢 已經(jīng)獨(dú)立完成過很多個項目 差不多80%的已經(jīng)上架到AppStore 有些個別的是公司內(nèi)部使用的
<a id="49">3. 開發(fā)過程中遇到過什么困難,是如何解決的?</a>
困難是遇到過很多 一些不好解決的坑都踩過 怎么解決的么 技術(shù)的扎實(shí)是一方面 還有就是多動腦 要從多個方面想解決辦法 然后還有就是沉下心來慢慢想辦法 不要難倒了幾分鐘就煩躁 這樣解決不了問題的
學(xué)習(xí)
<a id="50">1. 遇到一個問題完全不能理解的時候,是如何幫助自己理解的?舉個例子?</a>
舉個栗子??
這個說明你遇到的問題已經(jīng)超出你知識的領(lǐng)域 所以也不要靠你自己原本的知識去理解他 這時就要找解決辦法了,百度一下或者谷歌一下,如果有大牛的話 最好問問他們 詳細(xì)的講解一下 這樣比自己慢慢理解要來的快得多
<a id="51">2. 有看書的習(xí)慣么?最近看的一本是什么書?有什么心得?</a>
問:最近在看什么書?
答:簡書(哈哈哈~)
<a id="52">3. 有沒有使用一些筆記軟件?會在多平臺同步以及多渠道采集么?(如果沒有,問一下是如何復(fù)習(xí)知識的)</a>
這個的話我個人也嘗試用過很多筆記軟件 但是都差一點(diǎn)感覺 不知道是畫風(fēng)問題還是軟件的名字問題 但是我一直堅持使用的是系統(tǒng)自帶的備忘錄 就是簡單方便 沒有別的原因
<a id="53">4. 有沒有使用清單類,日歷類的軟件?(如果沒有,問一下是如何安排,計劃任務(wù)的)</a>
這個安排計劃和任務(wù)也是用的備忘錄??
<a id="54">5. 平??床┛兔??有沒有自己寫過?(如果寫,有哪些收獲?如果沒有寫,問一下不寫的原因)</a>
平時看博客 也看各類開發(fā)者網(wǎng)站 平時就提高自己技術(shù)的寬度和深度
寫的話還是在簡書上寫得多 比較喜歡簡書的風(fēng)格
總結(jié)
寫這篇文章呢 是我有一次在我關(guān)注的微信公眾號里看到的一篇文章 里面的內(nèi)容就是這里列的所有的問題 后來我才發(fā)現(xiàn)這個面試題在網(wǎng)上很早就有了 但是感覺全是題目沒有一個人整理過答案 我一想 這些題目對于正在或者即將想面試的ios開發(fā)者們有很大的幫助 也對自己是一個復(fù)習(xí)和學(xué)習(xí)的過程 這里面有一些問題的答案我是借鑒或轉(zhuǎn)載了前輩們的知識結(jié)晶 在這里我統(tǒng)一聲明一下 就不一一的艾特了 如果有冒犯 請多多原諒。