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