【2018年最新】 iOS面試題及答案(二)

ptlCoder發表於2018-02-08

#####1、HomeKit? 是蘋果2014年釋出的智慧家居平臺。

#####2、什麼是 OpenGL、Quartz 2D?

Quatarz 2d 是Apple提供的基本圖形工具庫。只是適用於2D圖形的繪製。 OpenGL,是一個跨平臺的圖形開發庫。適用於2D和3D圖形的繪製。

#####3、ffmpeg框架? ​ffmpeg 是音視訊處理工具,既有音視訊編碼解碼功能,又可以作為播放器使用。

#####4、談談 UITableView 的優化

1). 正確的複用cell。 2). 設計統一規格的Cell 3). 提前計算並快取好高度(佈局),因為heightForRowAtIndexPath:是呼叫最頻繁的方法; 4). 非同步繪製,遇到複雜介面,遇到效能瓶頸時,可能就是突破口; 4). 滑動時按需載入,這個在大量圖片展示,網路載入的時候很管用! 5). 減少子檢視的層級關係 6). 儘量使所有的檢視不透明化以及做切圓操作。 7). 不要動態的add 或者 remove 子控制元件。最好在初始化時就新增完,然後通過hidden來控制是否顯示。 8). 使用除錯工具分析問題。

#####5、如何實行cell的動態的行高

如果希望每條資料顯示自身的行高,必須設定兩個屬性,1.預估行高,2.自定義行高。 設定預估行高 tableView.estimatedRowHeight = 200。 設定定義行高 tableView.estimatedRowHeight = UITableViewAutomaticDimension。 如果要讓自定義行高有效,必須讓容器檢視有一個自下而上的約束。

#####6、說說你對 block 的理解

棧上的自動複製到堆上,block 的屬性修飾符是 copy,迴圈引用的原理和解決方案。

#####7、說說你對 runtime 的理解

主要是方法呼叫時如何查詢快取,如何找到方法,找不到方法時怎麼轉發,物件的記憶體佈局。

#####8、什麼是野指標、空指標?

野指標:不知道指向了哪裡的指標叫野指標。即指標指向不確定,指標存的地址是一個垃圾值,未初始化。 空指標:不指向任何位置的指標叫空指標。即指標沒有指向,指標存的地址是一個空地址,NULL。

#####9、什麼是 OOA / OOD / OOP ? OOA(Object Oriented Analysis) --物件導向分析 OOD(Object Oriented Design) --物件導向設計 OOP(Object Oriented Programming)--物件導向程式設計

#####10. 多執行緒是什麼

多執行緒是個複雜的概念,按字面意思是同步完成多項任務,提高了資源的使用效率,從硬體、作業系統、應用軟體不同的角度去看,多執行緒被賦予不同的內涵,對於硬體,現在市面上多數的CPU都是多核的,多核的CPU運算多執行緒更為出色;從作業系統角度,是多工,現在用的主流作業系統都是多工的,可以一邊聽歌、一邊寫部落格;對於應用來說,多執行緒可以讓應用有更快的迴應,可以在網路下載時,同時響應使用者的觸控操作。在iOS應用中,對多執行緒最初的理解,就是併發,它的含義是原來先做燒水,再摘菜,再炒菜的工作,會變成燒水的同時去摘菜,最後去炒菜。

#####11. iOS 中的多執行緒

iOS中的多執行緒,是Cocoa框架下的多執行緒,通過Cocoa的封裝,可以讓我們更為方便的使用執行緒,做過C++的同學可能會對執行緒有更多的理解,比如執行緒的創立,訊號量、共享變數有認識,Cocoa框架下會方便很多,它對執行緒做了封裝,有些封裝,可以讓我們建立的物件,本身便擁有執行緒,也就是執行緒的物件化抽象,從而減少我們的工程,提供程式的健壯性。

  • GCD是(Grand Central Dispatch)的縮寫 ,從系統級別提供的一個易用地多執行緒類庫,具有執行時的特點,能充分利用多核心硬體。GCD的API介面為C語言的函式,函式引數中多數有Block,關於Block的使用參看這裡,為我們提供強大的“介面”,對於GCD的使用參見本文

  • NSOperation與Queue

NSOperation是一個抽象類,它封裝了執行緒的細節實現,我們可以通過子類化該物件,加上NSQueue來同物件導向的思維,管理多執行緒程式。具體可參看這裡:一個基於NSOperation的多執行緒網路訪問的專案。

  • NSThread

NSThread是一個控制執行緒執行的物件,它不如NSOperation抽象,通過它我們可以方便的得到一個執行緒,並控制它。但NSThread的執行緒之間的併發控制,是需要我們自己來控制的,可以通過NSCondition實現。 參看 iOS多執行緒程式設計之NSThread的使用 其他多執行緒 在Cocoa的框架下,通知、Timer和非同步函式等都有使用多執行緒,(待補充).

#####12. 在專案什麼時候選擇使用GCD,什麼時候選擇NSOperation?

專案中使用NSOperation的優點是NSOperation是對執行緒的高度抽象,在專案中使用它,會使專案的程式結構更好,子類化NSOperation的設計思路,是具有物件導向的優點(複用、封裝),使得實現是多執行緒支援,而介面簡單,建議在複雜專案中使用。

專案中使用GCD的優點是GCD本身非常簡單、易用,對於不復雜的多執行緒操作,會節省程式碼量,而Block引數的使用,會是程式碼更為易讀,建議在簡單專案中使用。

#####13 KVO,NSNotification,delegate及block區別

  • KVO就是cocoa框架實現的觀察者模式,一般同KVC搭配使用,通過KVO可以監測一個值的變化,比如View的高度變化。是一對多的關係,一個值的變化會通知所有的觀察者。

  • NSNotification是通知,也是一對多的使用場景。在某些情況下,KVO和NSNotification是一樣的,都是狀態變化之後告知對方。NSNotification的特點,就是需要被觀察者先主動發出通知,然後觀察者註冊監聽後再來進行響應,比KVO多了傳送通知的一步,但是其優點是監聽不侷限於屬性的變化,還可以對多種多樣的狀態變化進行監聽,監聽範圍廣,使用也更靈活。

  • delegate 是代理,就是我不想做的事情交給別人做。比如狗需要吃飯,就通過delegate通知主人,主人就會給他做飯、盛飯、倒水,這些操作,這些狗都不需要關心,只需要呼叫delegate(代理人)就可以了,由其他類完成所需要的操作。所以delegate是一對一關係。

  • block是delegate的另一種形式,是函數語言程式設計的一種形式。使用場景跟delegate一樣,相比delegate更靈活,而且代理的實現更直觀。

  • KVO一般的使用場景是資料,需求是資料變化,比如股票價格變化,我們一般使用KVO(觀察者模式)。

  • delegate一般的使用場景是行為,需求是需要別人幫我做一件事情,比如買賣股票,我們一般使用delegate。

  • Notification一般是進行全域性通知,比如利好訊息一出,通知大家去買入。

  • delegate是強關聯,就是委託和代理雙方互相知道,你委託別人買股票你就需要知道經紀人,經紀人也不要知道自己的顧客。

  • Notification是弱關聯,利好訊息發出,你不需要知道是誰發的也可以做出相應的反應,同理發訊息的人也不需要知道接收的人也可以正常發出訊息。

#####14 將一個函式在主執行緒執行的4種方法

  • GCD方法,通過向主執行緒佇列傳送一個block塊,使block裡的方法可以在主執行緒中執行。
dispatch_async(dispatch_get_main_queue(), ^{      
    //需要執行的方法
});
複製程式碼
  • NSOperation 方法
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];  //主佇列
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
	//需要執行的方法
}];
[mainQueue addOperation:operation];
複製程式碼
  • NSThread 方法
[self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];

[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];

[[NSThread mainThread] performSelector:@selector(method) withObject:nil];
RunLoop方法
[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];
複製程式碼
  • RunLoop方法
[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];
複製程式碼

#####15、 如何讓計時器呼叫一個類方法

  • 計時器只能呼叫例項方法,但是可以在這個例項方法裡面呼叫靜態方法。
  • 使用計時器需要注意,計時器一定要加入RunLoop中,並且選好model才能執行。scheduledTimerWithTimeInterval方法建立一個計時器並加入到RunLoop中所以可以直接使用。
  • 如果計時器的repeats選擇YES說明這個計時器會重複執行,一定要在合適的時機呼叫計時器的invalid。不能在dealloc中呼叫,因為一旦設定為repeats 為yes,計時器會強持有self,導致dealloc永遠不會被呼叫,這個類就永遠無法被釋放。比如可以在viewDidDisappear中呼叫,這樣當類需要被回收的時候就可以正常進入dealloc中了。
 [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];

-(void)timerMethod
{
//呼叫類方法
	[[self class] staticMethod];
}

-(void)invalid
{
	[timer invalid];
	timer = nil;
}
複製程式碼

#####16、 如何重寫類方法

1、在子類中實現一個同基類名字一樣的靜態方法 2、在呼叫的時候不要使用類名呼叫,而是使用[self class]的方式呼叫。原理,用類名呼叫是早繫結,在編譯期繫結,用[self class]是晚繫結,在執行時決定呼叫哪個方法。

#####17、 NSTimer建立後,會在哪個執行緒執行。

用scheduledTimerWithTimeInterval建立的,在哪個執行緒建立就會被加入哪個執行緒的RunLoop中就執行在哪個執行緒 自己建立的Timer,加入到哪個執行緒的RunLoop中就執行在哪個執行緒。

#####18、 id和NSObject*的區別

id是一個 objc_object 結構體指標,定義是

typedef struct objc_object *id
複製程式碼
  • id可以理解為指向物件的指標。所有oc的物件 id都可以指向,編譯器不會做型別檢查,id呼叫任何存在的方法都不會在編譯階段報錯,當然如果這個id指向的物件沒有這個方法,該崩潰還是會崩潰的。

  • NSObject *指向的必須是NSObject的子類,呼叫的也只能是NSObjec裡面的方法否則就要做強制型別轉換。

  • 不是所有的OC物件都是NSObject的子類,還有一些繼承自NSProxy。NSObject *可指向的型別是id的子集。

#####19、淺談iOS開發中方法延遲執行的幾種方式?

  • Method1. performSelector方法
  • Method2. NSTimer定時器
  • Method3. NSThread執行緒的sleep
  • Method4. GCD
公用延遲執行方法:
- (void)delayMethod{ 
      NSLog(@"delayMethodEnd");
}
複製程式碼

######Method1:performSelector

[self performSelector:@selector(delayMethod) withObject:nil]
複製程式碼

可傳任意型別引數/ afterDelay:2.0]; 注:此方法是一種非阻塞的執行方式,未找到取消執行的方法。

程式執行結束 2015-08-31 10:56:59.361 CJDelayMethod[1080:39604] delayMethodStart2015-08-31 10:56:59.363 CJDelayMethod[1080:39604] nextMethod2015-08-31 10:57:01.364 CJDelayMethod[1080:39604] delayMethodEnd

Method2:NSTimer定時器
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(delayMethod) userInfo:nil repeats:NO];
複製程式碼

注:此方法是一種非阻塞的執行方式, 取消執行方法:- (void)invalidate;即可

程式執行結束 2015-08-31 10:58:10.182 CJDelayMethod[1129:41106] delayMethodStart2015-08-31 10:58:10.183 CJDelayMethod[1129:41106] nextMethod2015-08-31 10:58:12.185 CJDelayMethod[1129:41106] delayMethodEnd

Method3:NSThread執行緒的sleep
[NSThread sleepForTimeInterval:2.0];
複製程式碼

注:此方法是一種阻塞執行方式,建議放在子執行緒中執行,否則會卡住介面。但有時還是需要阻塞執行,如進入歡迎介面需要沉睡3秒才進入主介面時。 沒有找到取消執行方式。

程式執行結束 2015-08-31 10:58:41.501 CJDelayMethod[1153:41698] delayMethodStart2015-08-31 10:58:43.507 CJDelayMethod[1153:41698] nextMethod

Method4:GCD
__block ViewController/*主控制器*/ *weakSelf = self;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0/*延遲執行時間*/ * NSEC_PER_SEC));

dispatch_after(delayTime, dispatch_get_main_queue(), ^{
    [weakSelf delayMethod];
});`
複製程式碼

注:此方法可以在引數中選擇執行的執行緒,是一種非阻塞執行方式。沒有找到取消執行方式。

程式執行結束 2015-08-31 10:59:21.652 CJDelayMethod[1181:42438] delayMethodStart2015-08-31 10:59:21.653 CJDelayMethod[1181:42438] nextMethod2015-08-31 10:59:23.653 CJDelayMethod[1181:42438] delayMethodEnd

#####20、NSPersistentStoreCoordinator , NSManaged0bjectContext 和NSManaged0bject中的那些需要線上程中建立或者傳遞?

答:NSPersistentStoreCoordinator是持久化儲存協調者,主要用於協調託管物件上下文和持久化儲存區之間的關係。NSManagedObjectContext使用協調者的託管物件模型將資料儲存到資料庫,或查詢資料。

#####20、您是否做過一部的網路處理和通訊方面的工作?如果有,能具體介紹一下實現策略麼

答:使用NSOperation傳送非同步網路請求,使用NSOperationQueue管理執行緒數目及優先順序,底層是用NSURLConnetion,

#####21、你使用過Objective-C的執行時程式設計(Runtime Programming)麼?如果使用過,你用它做了什麼?你還能記得你所使用的相關的標頭檔案或者某些方法的名稱嗎?

答:Objecitve-C的重要特性是Runtime(執行時),在#import <objc/runtime.h> 下能看到相關的方法,用過objc_getClass()和class_copyMethodList()獲取過私有API;使用

Method method1 = class_getInstanceMethod(cls, sel1);
Method method2 = class_getInstanceMethod(cls, sel2);
method_exchangeImplementations(method1, method2);  
複製程式碼

程式碼交換兩個方法,在寫unit test時使用到。

#####22、Core開頭的系列的內容。是否使用過CoreAnimation和CoreGraphics。UI框架和CA,CG框架的聯絡是什麼?分別用CA和CG做過些什麼動畫或者影象上的內容。(有需要的話還可以涉及Quartz的一些內容)

答:UI框架的底層有CoreAnimation,CoreAnimation的底層有CoreGraphics。

UIKit
Core Animation
Core Graphics
Graphics Hardware

#####23、是否使用過CoreText或者CoreImage等?如果使用過,請談談你使用CoreText或者CoreImage的體驗。

答:CoreText可以解決複雜文字內容排版問題。CoreImage可以處理圖片,為其新增各種效果。體驗是很強大,挺複雜的。

#####24.NSNotification和KVO的區別和用法是什麼?什麼時候應該使用通知,什麼時候應該使用KVO,它們的實現上有什麼區別嗎?如果用protocol和delegate(或者delegate的Array)來實現類似的功能可能嗎?如果可能,會有什麼潛在的問題?如果不能,為什麼?

答:NSNotification是通知模式在iOS的實現, KVO的全稱是鍵值觀察(Key-value observing),其是基於KVC(key-value coding)的,KVC是一個通過屬性名訪問屬性變數的機制。例如將Module層的變化,通知到多個Controller物件時,可以使用NSNotification;如果是隻需要觀察某個物件的某個屬性,可以使用KVO。 對於委託模式,在設計模式中是物件介面卡模式,其是delegate是指向某個物件的,這是一對一的關係,而在通知模式中,往往是一對多的關係。委託模式,從技術上可以現在改變delegate指向的物件,但不建議這樣做,會讓人迷惑,如果一個delegate物件不斷改變,指向不同的物件。

#####25、你用過NSOperationQueue麼?如果用過或者瞭解的話,你為什麼要使用NSOperationQueue,實現了什麼?請描述它和G.C.D的區別和類似的地方(提示:可以從兩者的實現機制和適用範圍來描述)。

答:使用NSOperationQueue用來管理子類化的NSOperation物件,控制其執行緒併發數目。GCD和NSOperation都可以實現對執行緒的管理,區別是 NSOperation和NSOperationQueue是多執行緒的物件導向抽象。專案中使用NSOperation的優點是NSOperation是對執行緒的高度抽象,在專案中使用它,會使專案的程式結構更好,子類化NSOperation的設計思路,是具有物件導向的優點(複用、封裝),使得實現是多執行緒支援,而介面簡單,建議在複雜專案中使用。 專案中使用GCD的優點是GCD本身非常簡單、易用,對於不復雜的多執行緒操作,會節省程式碼量,而Block引數的使用,會是程式碼更為易讀,建議在簡單專案中使用。

#####26、既然提到G.C.D,那麼問一下在使用G.C.D以及block時要注意些什麼?它們兩是一回事兒麼?block在ARC中和傳統的MRC中的行為和用法有沒有什麼區別,需要注意些什麼?

答:使用block是要注意,若將block做函式引數時,需要把它放到最後,GCD是Grand Central Dispatch,是一個對執行緒開源類庫,而Block是閉包,是能夠讀取其他函式內部變數的函式。

#####27、對於Objective-C,你認為它最大的優點和最大的不足是什麼?對於不足之處,現在有沒有可用的方法繞過這些不足來實現需求。如果可以的話,你有沒有考慮或者實踐過重新實現OC的一些功能,如果有,具體會如何做?

答:最大的優點是它的執行時特性,不足是沒有名稱空間,對於命名衝突,可以使用長命名法或特殊字首解決,如果是引入的第三方庫之間的命名衝突,可以使用link命令及flag解決衝突。

#####28、你實現過一個框架或者庫以供別人使用麼?如果有,請談一談構建框架或者庫時候的經驗;如果沒有,請設想和設計框架的public的API,並指出大概需要如何做、需要注意一些什麼方面,來使別人容易地使用你的框架。

答:抽象和封裝,方便使用。首先是對問題有充分的瞭解,比如構建一個檔案解壓壓縮框架,從使用者的角度出發,只需關注傳送給框架一個解壓請求,框架完成複雜檔案的解壓操作,並且在適當的時候通知給是哦難過者,如解壓完成、解壓出錯等。在框架內部去構建物件的關係,通過抽象讓其更為健壯、便於更改。其次是API的說明文件。


qq技術交流群

qq交流群.jpeg
作者微信公眾號
微信公眾號.jpg

相關文章