通過自己的工作經驗和面試經歷小結了一份iOS面試題 分享出來 歡迎指正和補充!
如果你懶得看文字, 可以直接瀏覽前面的思維導圖(本人使用的是MindNode)







基礎
1: @class的作用?
(1) @class告訴編譯器某個類的聲明 當執(zhí)行時 才去查看類的實現(xiàn)文件 可以解決頭文件的相互包含
(2) @class能提高編譯效率 由于在h文件中 使用#import的話 是將其內容全部拷貝過來 會影響編譯效率 而且對應的h文件只有有任何改動 又要重新編譯
2: @synthesize和@dynamic分別有什么作用?
@synthesize的語義是如果你沒有手動實現(xiàn)setter方法和getter方法 那么編譯器會自動為你加上這兩個方法
@dynamic告訴編譯器屬性的setter與getter方法由用戶自己實現(xiàn) 不自動生成 如果沒有實現(xiàn)的話 那么運行時會發(fā)生崩潰
3: #import和#include的區(qū)別?
(1) #import是O-C導入頭文件的關鍵字 #include是C/C++導入頭文件的關鍵字
(2) #import比起#include的好處就是不會引起重復包含
4: nil和NULL的區(qū)別?
(1) nil表示為空的O-C對象
(2) NULL表示空指針(不指向任何內存地址)
5: id、instanceType和void *的區(qū)別?
(1) id是指針 指向任何一個繼承自NSObject的對象
(2) instanceType只能作為返回值 返回和方法所在類相同類型的對象
(3) void *則為"無類型指針" 可以指向任何數(shù)據類型
更多請參考Objective-C小結
語法
1: 什么是block?
類似匿名函數(shù) (實質是對象)
什么時候使用block?
通常在異步請求時使用 (尤其注意view controller間通信推薦使用delegate 而不是block)
使用block有什么需要注意的地方?
防止循環(huán)引用
2: Objective-C中category的特點?
(1) 在不獲悉不改變原來代碼的情況下往里面添加新的方法
(2) 將類的實現(xiàn)分散到多個不同文件或多個不同框架中
(3) 可以訪問原始類的實例變量 但不能添加變量 (其實可以用過runtime的assosiated object來實現(xiàn))
(4) 不能重載primary class的方法(這個算是category相比繼承的劣勢吧)
繼承相比category相比有何劣勢?
(1) 成本高: 必須要熟悉父類 (而category不需要了解primary class就可以進行擴展)
(2) 耦合高: 子類依賴父類
(3) 復雜度高: 當繼承體系較復雜時
3: Objective-C相比其他語言有哪些”缺點”?
(1) 沒有命名空間機制: 為了區(qū)分不同的類 在類名前加前綴
(2) 不支持多重繼承: 但可以通過protocol和delegate pattern來代替
(3) 不支持抽象基類(abstract class): 要想達成類似效果 可以在子類必須覆寫的父類方法里拋出異常
4: 是否使用過Swift?
Swift相比Objective-C有哪些更友好的特性? (可選類型, 異常處理, 函數(shù)式編程)
Objective-C和Swift混編, 詳細請參考iOS開發(fā) 之 Objective-C和Swift混合編程
內存
1: 什么是ARC? (auto reference count)
ARC屬性修飾符有哪些? (strong weak copy assign readonly readwrite)
它們分別在什么時候使用? (strong保持該對象不被銷毀 weak主要應用于delegate和block copy主要應用于string asking主要應用于內置數(shù)據類型如NSInteger BOOL等)
weak和assign有何區(qū)別? (weak = assign + 引用對象銷毀時自動置nil 所以使用weak引用對象更安全)
view controller中的sub view成員一般使用哪一種修飾符? (weak 因為view controller強引用了root view root view又強引用了subview 因為sub view的owner是root view而非view controller 所以使用weak相比于strong可以避免過度使用強引用)
2: 什么是循環(huán)引用? (對象相互強引用彼此)
如何解決強引用? 思路是打破相互強引用形成的循環(huán)引用
(1) 使用弱引用 例如delegate和block中使用weak
(2) 不使用強引用對象時及時將引用置為nil
舉個你遇到過的循環(huán)引用的例子?
(1) block里面應用了self.property
(2) http request在block中應用了self, 但是沒有在vc銷毀后cancel task
(3) NSTimer沒有正確銷毀, 詳細請參考iOS開發(fā) 之 不要告訴我你會用NSTimer
3: 是否使用過對象拷貝?
深拷貝(shallow copy)和淺拷貝(deep copy)的區(qū)別?
(1) 淺復制: 復制指向對象的指針
(2) 深復制: 復制引用對象本身
Objective-C中的對象拷貝要實現(xiàn)什么protocol? (NSCopying)
更多請參考Objective-C學習 之 對象拷貝
開發(fā)
1: UIViewController生命周期有哪些?
load(在加載該類時調用) -> initialize(在該類第一次創(chuàng)建對象時調用) -> init
-> loadView(代碼創(chuàng)建) or initWithNib(nib創(chuàng)建)
-> viewDidLoad (不要在這里設置frame!!!)
-> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear
-> viewWillDisappear -> viewDidDisappear
-> dealloc
2: UIApplication生命周期有哪些?
willFinishLaunchingWithOptions -> didFinishLaunchingWithOptions
-> (applicationWillEnterForeground) -> applicationDidBecomeActive
-> applicationWillResignActive -> applicationDidEnterBackground
-> applicationWillTerminate
3: iOS中多線程有哪些方式? (pthread NSThread GCD NSOperation)
各有何優(yōu)缺點? (pthread是Unix, Linux, MacOS下的一套多線程APIs NSThread功能較簡單但需要自己管理線程 GCD簡單高效但當過度使用會造成線程調用混亂 NSoperation功能強大且接口一致推薦使用)
4: 本地持久化可以采取哪些方案?
NSUserDefaults儲存基本數(shù)據類型的簡單數(shù)據
NSKeyedArchiver存儲對象
sqlite(使用第三方庫FMDB, 數(shù)據加密請參考iOS工具 之 FMDB+SQLCipher)
core data(Apple官方替代db的方案 使用第三方庫MagicalRecord)
realm(新興的本地持久化方案)
6: 如何做屏幕適配?
(1) 代碼方式的第三方庫: masonry, pure layout等
(2) storyboard/xib布局
在屏幕適配過程中遇到了哪些問題?
代碼布局以及storyboard/xib在開發(fā)中的優(yōu)劣勢?
設計
1: 寫一個單例設計模式? (允許答題者上網查找)
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[super allocWithZone:NULL] init];
});
return sharedInstance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstance];
}
+ (id)copyWithZone:(struct _NSZone *)zone {
return [self sharedInstance];
}
- (id)copy {
return self;
}
2: Delegate和Proxy模式的區(qū)別?
Delegate是委托, 即兩者之間的通信
Proxy是代理, 即第三者起到保護和控制的作用
詳細請參考設計模式 之 Proxy
3: MVC MVP MVVM
iOS開發(fā)中MVP架構較少, MVVM的第三方庫有ReactiveCocoa, RxSwfit
詳細請參考iOS開發(fā) 之 架構模式MVC/MVP/MVVM
4: notification和delegate以及KVO的區(qū)分和用途?
notification是廣播 即1對多的通信方式(廣播方不知道接收方)
delegate是委托 即1對1的通信方式(是iOS中常見且推薦的通信方式)
KVO是觀察者模式的應用 也是1對多的通信方式(被觀察者是知道有哪些觀察者的)
5: 如何優(yōu)化UITableView性能?
(1) 壓縮圖片(縮略圖 ImageOptim Webp)
(2) UITableViewCell復用
(3) 耗時操作和計算放置異步線程
(4) facebook的方案: AsyncDisplayKit
6: 一些常用的設計原則
(1) 一元: 統(tǒng)一使用delegate進行模塊解耦; 數(shù)據格式統(tǒng)一為JSON且key統(tǒng)一為String
(2) 接口: 接口功能單一, 簡單, 參數(shù)少, 易理解; 接口面向接口編程而非實現(xiàn); 進行單元測試
(3) 分層: 避免橫向依賴; 沒有跨層訪問
(4) 網絡層和本地持久化: 隔離數(shù)據的處理和表示; 串行化
高階
1: 什么是事件響應鏈?
Touch Event發(fā)生時, iOS將其封裝成UIEvent對象, 放在當前App的的Event Queue中
UIApplication Runloop從Event Queue中取出該Event進行disptach for handling
Dispatch for hanlding該event的view的過程, 就叫hit-testing
而最終handling該event的view, 就叫hit-test view
舉出使用事件響應鏈的例子?
(1) 使用第三方庫DAСontextMenuCell, 讓上層的OverLay View的事件響應透傳至下層View
- hitTest:withEvent:
(2) 劃出側邊欄和cell側滑響應事件的處理, 使用了
- gestureRecognizer:shouldReceiveTouch:
2: 什么是反射? (運行時獲取或改變程序信息)
Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime
詳細請參考談談移動開發(fā)編程中的反射(Reflection)
3: Runtime有哪些引用場景?
(1) 要在按鈕點擊時全局加上統(tǒng)計信息, 使用了Method Swizzling(使用第三方庫Aspects)
(2) 要在category里添加新的屬性, 使用了Associated Object(只有assign沒有weak屬性修飾符, 所以需要在銷毀時手動置nil)
load和initialize的區(qū)別?
(1) load會在第一次加載該類時調用, 且包含category
(2) initialize只在該類第一次創(chuàng)建對象時調用, 對category無效
4: Runloop及其應用?
詳細請參考
以及
產品
1: 代碼規(guī)范
詳細請參考Objective-C編程規(guī)范
2: 常用的第三庫有哪些?
AFNetworking YYkit MJExtension
FMDB Realm
SDWebImage
Masonry TPKeyboardAvoiding
fastlane
3: 有哪些安全措施?
(1) 編碼
Base64使用64個字符來對任意數(shù)據進行編碼 過程是可逆的 目的是把含有不可見字符串的信息用可見字符串表示出來
MD5生成的是固定的128bit 過程不可逆 常用來保存密碼信息
SHA-256生成的是固定的256bit 加強版的MD5安全性更高
DES對稱加密算法 密鑰既能加密也能解密
AES加強版的DES 安全性更高 加密速度更快
RSA非對稱加密算法 更安全 但加密速度不如對稱加密算法
(2) HTTPS(證書)
(3) 數(shù)據庫加密, 參考iOS工具 之 FMDB+SQLCipher
4: 持續(xù)集成和自動化發(fā)布
Jenkins
或者
TravisCI, 詳細請參考TravisDemo + fir
更多文章, 請支持我的個人博客