1、HomeKit?
是蘋果2014年發(fā)布的智能家居平臺(tái)。
2、什么是 OpenGL、Quartz 2D?
Quatarz 2d 是Apple提供的基本圖形工具庫(kù)。只是適用于2D圖形的繪制。
OpenGL,是一個(gè)跨平臺(tái)的圖形開發(fā)庫(kù)。適用于2D和3D圖形的繪制。
3、ffmpeg框架?
ffmpeg 是音視頻處理工具,既有音視頻編碼解碼功能,又可以作為播放器使用。
4、談?wù)?UITableView 的優(yōu)化
1). 正確的復(fù)用cell。
2). 設(shè)計(jì)統(tǒng)一規(guī)格的Cell
3). 提前計(jì)算并緩存好高度(布局),因?yàn)閔eightForRowAtIndexPath:是調(diào)用最頻繁的方法;
4). 異步繪制,遇到復(fù)雜界面,遇到性能瓶頸時(shí),可能就是突破口;
4). 滑動(dòng)時(shí)按需加載,這個(gè)在大量圖片展示,網(wǎng)絡(luò)加載的時(shí)候很管用!
5). 減少子視圖的層級(jí)關(guān)系
6). 盡量使所有的視圖不透明化以及做切圓操作。
7). 不要?jiǎng)討B(tài)的add 或者 remove 子控件。最好在初始化時(shí)就添加完,然后通過(guò)hidden來(lái)控制是否顯示。
8). 使用調(diào)試工具分析問(wèn)題。
5、如何實(shí)行cell的動(dòng)態(tài)的行高
如果希望每條數(shù)據(jù)顯示自身的行高,必須設(shè)置兩個(gè)屬性,1.預(yù)估行高,2.自定義行高。
設(shè)置預(yù)估行高 tableView.estimatedRowHeight = 200。
設(shè)置定義行高 tableView.estimatedRowHeight = UITableViewAutomaticDimension。
如果要讓自定義行高有效,必須讓容器視圖有一個(gè)自下而上的約束。
6、說(shuō)說(shuō)你對(duì) block 的理解
棧上的自動(dòng)復(fù)制到堆上,block 的屬性修飾符是 copy,循環(huán)引用的原理和解決方案。
7、說(shuō)說(shuō)你對(duì) runtime 的理解
主要是方法調(diào)用時(shí)如何查找緩存,如何找到方法,找不到方法時(shí)怎么轉(zhuǎn)發(fā),對(duì)象的內(nèi)存布局。
8、什么是野指針、空指針?
野指針:不知道指向了哪里的指針叫野指針。即指針指向不確定,指針存的地址是一個(gè)垃圾值,未初始化。
空指針:不指向任何位置的指針叫空指針。即指針沒有指向,指針存的地址是一個(gè)空地址,NULL。
9、什么是 OOA / OOD / OOP ?
OOA(Object Oriented Analysis) --面向?qū)ο蠓治?/p>
OOD(Object Oriented Design) --面向?qū)ο笤O(shè)計(jì)
OOP(Object Oriented Programming)--面向?qū)ο缶幊?/p>
10. 多線程是什么
多線程是個(gè)復(fù)雜的概念,按字面意思是同步完成多項(xiàng)任務(wù),提高了資源的使用效率,從硬件、操作系統(tǒng)、應(yīng)用軟件不同的角度去看,多線程被賦予不同的內(nèi)涵,對(duì)于硬件,現(xiàn)在市面上多數(shù)的CPU都是多核的,多核的CPU運(yùn)算多線程更為出色;從操作系統(tǒng)角度,是多任務(wù),現(xiàn)在用的主流操作系統(tǒng)都是多任務(wù)的,可以一邊聽歌、一邊寫博客;對(duì)于應(yīng)用來(lái)說(shuō),多線程可以讓應(yīng)用有更快的回應(yīng),可以在網(wǎng)絡(luò)下載時(shí),同時(shí)響應(yīng)用戶的觸摸操作。在iOS應(yīng)用中,對(duì)多線程最初的理解,就是并發(fā),它的含義是原來(lái)先做燒水,再摘菜,再炒菜的工作,會(huì)變成燒水的同時(shí)去摘菜,最后去炒菜。
11. iOS 中的多線程
iOS中的多線程,是Cocoa框架下的多線程,通過(guò)Cocoa的封裝,可以讓我們更為方便的使用線程,做過(guò)C++的同學(xué)可能會(huì)對(duì)線程有更多的理解,比如線程的創(chuàng)立,信號(hào)量、共享變量有認(rèn)識(shí),Cocoa框架下會(huì)方便很多,它對(duì)線程做了封裝,有些封裝,可以讓我們創(chuàng)建的對(duì)象,本身便擁有線程,也就是線程的對(duì)象化抽象,從而減少我們的工程,提供程序的健壯性。
- GCD是(Grand Central Dispatch)的縮寫 ,從系統(tǒng)級(jí)別提供的一個(gè)易用地多線程類庫(kù),具有運(yùn)行時(shí)的特點(diǎn),能充分利用多核心硬件。GCD的API接口為C語(yǔ)言的函數(shù),函數(shù)參數(shù)中多數(shù)有Block,關(guān)于Block的使用參看這里,為我們提供強(qiáng)大的“接口”,對(duì)于GCD的使用參見本文
- NSOperation與Queue
NSOperation是一個(gè)抽象類,它封裝了線程的細(xì)節(jié)實(shí)現(xiàn),我們可以通過(guò)子類化該對(duì)象,加上NSQueue來(lái)同面向?qū)ο蟮乃季S,管理多線程程序。具體可參看這里:一個(gè)基于NSOperation的多線程網(wǎng)絡(luò)訪問(wèn)的項(xiàng)目。
- NSThread
NSThread是一個(gè)控制線程執(zhí)行的對(duì)象,它不如NSOperation抽象,通過(guò)它我們可以方便的得到一個(gè)線程,并控制它。但NSThread的線程之間的并發(fā)控制,是需要我們自己來(lái)控制的,可以通過(guò)NSCondition實(shí)現(xiàn)。
參看 iOS多線程編程之NSThread的使用
其他多線程
在Cocoa的框架下,通知、Timer和異步函數(shù)等都有使用多線程,(待補(bǔ)充).
12. 在項(xiàng)目什么時(shí)候選擇使用GCD,什么時(shí)候選擇NSOperation?
項(xiàng)目中使用NSOperation的優(yōu)點(diǎn)是NSOperation是對(duì)線程的高度抽象,在項(xiàng)目中使用它,會(huì)使項(xiàng)目的程序結(jié)構(gòu)更好,子類化NSOperation的設(shè)計(jì)思路,是具有面向?qū)ο蟮膬?yōu)點(diǎn)(復(fù)用、封裝),使得實(shí)現(xiàn)是多線程支持,而接口簡(jiǎn)單,建議在復(fù)雜項(xiàng)目中使用。
項(xiàng)目中使用GCD的優(yōu)點(diǎn)是GCD本身非常簡(jiǎn)單、易用,對(duì)于不復(fù)雜的多線程操作,會(huì)節(jié)省代碼量,而Block參數(shù)的使用,會(huì)是代碼更為易讀,建議在簡(jiǎn)單項(xiàng)目中使用。
13 KVO,NSNotification,delegate及block區(qū)別
KVO就是cocoa框架實(shí)現(xiàn)的觀察者模式,一般同KVC搭配使用,通過(guò)KVO可以監(jiān)測(cè)一個(gè)值的變化,比如View的高度變化。是一對(duì)多的關(guān)系,一個(gè)值的變化會(huì)通知所有的觀察者。
NSNotification是通知,也是一對(duì)多的使用場(chǎng)景。在某些情況下,KVO和NSNotification是一樣的,都是狀態(tài)變化之后告知對(duì)方。NSNotification的特點(diǎn),就是需要被觀察者先主動(dòng)發(fā)出通知,然后觀察者注冊(cè)監(jiān)聽后再來(lái)進(jìn)行響應(yīng),比KVO多了發(fā)送通知的一步,但是其優(yōu)點(diǎn)是監(jiān)聽不局限于屬性的變化,還可以對(duì)多種多樣的狀態(tài)變化進(jìn)行監(jiān)聽,監(jiān)聽范圍廣,使用也更靈活。
- delegate 是代理,就是我不想做的事情交給別人做。比如狗需要吃飯,就通過(guò)delegate通知主人,主人就會(huì)給他做飯、盛飯、倒水,這些操作,這些狗都不需要關(guān)心,只需要調(diào)用delegate(代理人)就可以了,由其他類完成所需要的操作。所以delegate是一對(duì)一關(guān)系。
- block是delegate的另一種形式,是函數(shù)式編程的一種形式。使用場(chǎng)景跟delegate一樣,相比delegate更靈活,而且代理的實(shí)現(xiàn)更直觀。
KVO一般的使用場(chǎng)景是數(shù)據(jù),需求是數(shù)據(jù)變化,比如股票價(jià)格變化,我們一般使用KVO(觀察者模式)。
delegate一般的使用場(chǎng)景是行為,需求是需要?jiǎng)e人幫我做一件事情,比如買賣股票,我們一般使用delegate。
Notification一般是進(jìn)行全局通知,比如利好消息一出,通知大家去買入。
delegate是強(qiáng)關(guān)聯(lián),就是委托和代理雙方互相知道,你委托別人買股票你就需要知道經(jīng)紀(jì)人,經(jīng)紀(jì)人也不要知道自己的顧客。
Notification是弱關(guān)聯(lián),利好消息發(fā)出,你不需要知道是誰(shuí)發(fā)的也可以做出相應(yīng)的反應(yīng),同理發(fā)消息的人也不需要知道接收的人也可以正常發(fā)出消息。
14 將一個(gè)函數(shù)在主線程執(zhí)行的4種方法
- GCD方法,通過(guò)向主線程隊(duì)列發(fā)送一個(gè)block塊,使block里的方法可以在主線程中執(zhí)行。
dispatch_async(dispatch_get_main_queue(), ^{
//需要執(zhí)行的方法
});
- NSOperation 方法
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; //主隊(duì)列
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//需要執(zhí)行的方法
}];
[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、 如何讓計(jì)時(shí)器調(diào)用一個(gè)類方法
計(jì)時(shí)器只能調(diào)用實(shí)例方法,但是可以在這個(gè)實(shí)例方法里面調(diào)用靜態(tài)方法。
使用計(jì)時(shí)器需要注意,計(jì)時(shí)器一定要加入RunLoop中,并且選好model才能運(yùn)行。scheduledTimerWithTimeInterval方法創(chuàng)建一個(gè)計(jì)時(shí)器并加入到RunLoop中所以可以直接使用。
如果計(jì)時(shí)器的repeats選擇YES說(shuō)明這個(gè)計(jì)時(shí)器會(huì)重復(fù)執(zhí)行,一定要在合適的時(shí)機(jī)調(diào)用計(jì)時(shí)器的invalid。不能在dealloc中調(diào)用,因?yàn)橐坏┰O(shè)置為repeats 為yes,計(jì)時(shí)器會(huì)強(qiáng)持有self,導(dǎo)致dealloc永遠(yuǎn)不會(huì)被調(diào)用,這個(gè)類就永遠(yuǎn)無(wú)法被釋放。比如可以在viewDidDisappear中調(diào)用,這樣當(dāng)類需要被回收的時(shí)候就可以正常進(jìn)入dealloc中了。
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
-(void)timerMethod
{
//調(diào)用類方法
[[self class] staticMethod];
}
-(void)invalid
{
[timer invalid];
timer = nil;
}
16、 如何重寫類方法
1、在子類中實(shí)現(xiàn)一個(gè)同基類名字一樣的靜態(tài)方法
2、在調(diào)用的時(shí)候不要使用類名調(diào)用,而是使用[self class]的方式調(diào)用。原理,用類名調(diào)用是早綁定,在編譯期綁定,用[self class]是晚綁定,在運(yùn)行時(shí)決定調(diào)用哪個(gè)方法。
17、 NSTimer創(chuàng)建后,會(huì)在哪個(gè)線程運(yùn)行。
用scheduledTimerWithTimeInterval創(chuàng)建的,在哪個(gè)線程創(chuàng)建就會(huì)被加入哪個(gè)線程的RunLoop中就運(yùn)行在哪個(gè)線程
自己創(chuàng)建的Timer,加入到哪個(gè)線程的RunLoop中就運(yùn)行在哪個(gè)線程。
18、 id和NSObject*的區(qū)別
id是一個(gè) objc_object 結(jié)構(gòu)體指針,定義是
typedef struct objc_object *id
- id可以理解為指向?qū)ο蟮闹羔?。所有oc的對(duì)象 id都可以指向,編譯器不會(huì)做類型檢查,id調(diào)用任何存在的方法都不會(huì)在編譯階段報(bào)錯(cuò),當(dāng)然如果這個(gè)id指向的對(duì)象沒有這個(gè)方法,該崩潰還是會(huì)崩潰的。
- NSObject *指向的必須是NSObject的子類,調(diào)用的也只能是NSObjec里面的方法否則就要做強(qiáng)制類型轉(zhuǎn)換。
- 不是所有的OC對(duì)象都是NSObject的子類,還有一些繼承自NSProxy。NSObject *可指向的類型是id的子集。
19、淺談iOS開發(fā)中方法延遲執(zhí)行的幾種方式?
Method1. performSelector方法
Method2. NSTimer定時(shí)器
Method3. NSThread線程的sleep
Method4. GCD
公用延遲執(zhí)行方法:
- (void)delayMethod{
NSLog(@"delayMethodEnd");
}
Method1:performSelector
[self performSelector:@selector(delayMethod) withObject:nil]
可傳任意類型參數(shù)/ afterDelay:2.0];
注:此方法是一種非阻塞的執(zhí)行方式,未找到取消執(zhí)行的方法。
程序運(yùn)行結(jié)束
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定時(shí)器
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(delayMethod) userInfo:nil repeats:NO];
注:此方法是一種非阻塞的執(zhí)行方式,
取消執(zhí)行方法:- (void)invalidate;即可
程序運(yùn)行結(jié)束
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];
注:此方法是一種阻塞執(zhí)行方式,建議放在子線程中執(zhí)行,否則會(huì)卡住界面。但有時(shí)還是需要阻塞執(zhí)行,如進(jìn)入歡迎界面需要沉睡3秒才進(jìn)入主界面時(shí)。
沒有找到取消執(zhí)行方式。
程序運(yùn)行結(jié)束
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/*延遲執(zhí)行時(shí)間*/ * NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), ^{
[weakSelf delayMethod];
});`
注:此方法可以在參數(shù)中選擇執(zhí)行的線程,是一種非阻塞執(zhí)行方式。沒有找到取消執(zhí)行方式。
程序運(yùn)行結(jié)束
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中的那些需要在線程中創(chuàng)建或者傳遞?
答:NSPersistentStoreCoordinator是持久化存儲(chǔ)協(xié)調(diào)者,主要用于協(xié)調(diào)托管對(duì)象上下文和持久化存儲(chǔ)區(qū)之間的關(guān)系。NSManagedObjectContext使用協(xié)調(diào)者的托管對(duì)象模型將數(shù)據(jù)保存到數(shù)據(jù)庫(kù),或查詢數(shù)據(jù)。
20、您是否做過(guò)一部的網(wǎng)絡(luò)處理和通訊方面的工作?如果有,能具體介紹一下實(shí)現(xiàn)策略么
答:使用NSOperation發(fā)送異步網(wǎng)絡(luò)請(qǐng)求,使用NSOperationQueue管理線程數(shù)目及優(yōu)先級(jí),底層是用NSURLConnetion,
21、你使用過(guò)Objective-C的運(yùn)行時(shí)編程(Runtime Programming)么?如果使用過(guò),你用它做了什么?你還能記得你所使用的相關(guān)的頭文件或者某些方法的名稱嗎?
答:Objecitve-C的重要特性是Runtime(運(yùn)行時(shí)),在#import <objc/runtime.h> 下能看到相關(guān)的方法,用過(guò)objc_getClass()和class_copyMethodList()獲取過(guò)私有API;使用
Method method1 = class_getInstanceMethod(cls, sel1);
Method method2 = class_getInstanceMethod(cls, sel2);
method_exchangeImplementations(method1, method2);
代碼交換兩個(gè)方法,在寫unit test時(shí)使用到。
22、Core開頭的系列的內(nèi)容。是否使用過(guò)CoreAnimation和CoreGraphics。UI框架和CA,CG框架的聯(lián)系是什么?分別用CA和CG做過(guò)些什么動(dòng)畫或者圖像上的內(nèi)容。(有需要的話還可以涉及Quartz的一些內(nèi)容)
答:UI框架的底層有CoreAnimation,CoreAnimation的底層有CoreGraphics。
UIKit |
------------ |
Core Animation |
Core Graphics |
Graphics Hardware|
23、是否使用過(guò)CoreText或者CoreImage等?如果使用過(guò),請(qǐng)談?wù)勀闶褂肅oreText或者CoreImage的體驗(yàn)。
答:CoreText可以解決復(fù)雜文字內(nèi)容排版問(wèn)題。CoreImage可以處理圖片,為其添加各種效果。體驗(yàn)是很強(qiáng)大,挺復(fù)雜的。
24.NSNotification和KVO的區(qū)別和用法是什么?什么時(shí)候應(yīng)該使用通知,什么時(shí)候應(yīng)該使用KVO,它們的實(shí)現(xiàn)上有什么區(qū)別嗎?如果用protocol和delegate(或者delegate的Array)來(lái)實(shí)現(xiàn)類似的功能可能嗎?如果可能,會(huì)有什么潛在的問(wèn)題?如果不能,為什么?
答:NSNotification是通知模式在iOS的實(shí)現(xiàn),
KVO的全稱是鍵值觀察(Key-value observing),其是基于KVC(key-value coding)的,KVC是一個(gè)通過(guò)屬性名訪問(wèn)屬性變量的機(jī)制。例如將Module層的變化,通知到多個(gè)Controller對(duì)象時(shí),可以使用NSNotification;如果是只需要觀察某個(gè)對(duì)象的某個(gè)屬性,可以使用KVO。
對(duì)于委托模式,在設(shè)計(jì)模式中是對(duì)象適配器模式,其是delegate是指向某個(gè)對(duì)象的,這是一對(duì)一的關(guān)系,而在通知模式中,往往是一對(duì)多的關(guān)系。委托模式,從技術(shù)上可以現(xiàn)在改變delegate指向的對(duì)象,但不建議這樣做,會(huì)讓人迷惑,如果一個(gè)delegate對(duì)象不斷改變,指向不同的對(duì)象。
25、你用過(guò)NSOperationQueue么?如果用過(guò)或者了解的話,你為什么要使用NSOperationQueue,實(shí)現(xiàn)了什么?請(qǐng)描述它和G.C.D的區(qū)別和類似的地方(提示:可以從兩者的實(shí)現(xiàn)機(jī)制和適用范圍來(lái)描述)。
答:使用NSOperationQueue用來(lái)管理子類化的NSOperation對(duì)象,控制其線程并發(fā)數(shù)目。GCD和NSOperation都可以實(shí)現(xiàn)對(duì)線程的管理,區(qū)別是 NSOperation和NSOperationQueue是多線程的面向?qū)ο蟪橄蟆m?xiàng)目中使用NSOperation的優(yōu)點(diǎn)是NSOperation是對(duì)線程的高度抽象,在項(xiàng)目中使用它,會(huì)使項(xiàng)目的程序結(jié)構(gòu)更好,子類化NSOperation的設(shè)計(jì)思路,是具有面向?qū)ο蟮膬?yōu)點(diǎn)(復(fù)用、封裝),使得實(shí)現(xiàn)是多線程支持,而接口簡(jiǎn)單,建議在復(fù)雜項(xiàng)目中使用。
項(xiàng)目中使用GCD的優(yōu)點(diǎn)是GCD本身非常簡(jiǎn)單、易用,對(duì)于不復(fù)雜的多線程操作,會(huì)節(jié)省代碼量,而Block參數(shù)的使用,會(huì)是代碼更為易讀,建議在簡(jiǎn)單項(xiàng)目中使用。
26、既然提到G.C.D,那么問(wèn)一下在使用G.C.D以及block時(shí)要注意些什么?它們兩是一回事兒么?block在ARC中和傳統(tǒng)的MRC中的行為和用法有沒有什么區(qū)別,需要注意些什么?
答:使用block是要注意,若將block做函數(shù)參數(shù)時(shí),需要把它放到最后,GCD是Grand Central Dispatch,是一個(gè)對(duì)線程開源類庫(kù),而Block是閉包,是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。
27、對(duì)于Objective-C,你認(rèn)為它最大的優(yōu)點(diǎn)和最大的不足是什么?對(duì)于不足之處,現(xiàn)在有沒有可用的方法繞過(guò)這些不足來(lái)實(shí)現(xiàn)需求。如果可以的話,你有沒有考慮或者實(shí)踐過(guò)重新實(shí)現(xiàn)OC的一些功能,如果有,具體會(huì)如何做?
答:最大的優(yōu)點(diǎn)是它的運(yùn)行時(shí)特性,不足是沒有命名空間,對(duì)于命名沖突,可以使用長(zhǎng)命名法或特殊前綴解決,如果是引入的第三方庫(kù)之間的命名沖突,可以使用link命令及flag解決沖突。
28、你實(shí)現(xiàn)過(guò)一個(gè)框架或者庫(kù)以供別人使用么?如果有,請(qǐng)談一談構(gòu)建框架或者庫(kù)時(shí)候的經(jīng)驗(yàn);如果沒有,請(qǐng)?jiān)O(shè)想和設(shè)計(jì)框架的public的API,并指出大概需要如何做、需要注意一些什么方面,來(lái)使別人容易地使用你的框架。
答:抽象和封裝,方便使用。首先是對(duì)問(wèn)題有充分的了解,比如構(gòu)建一個(gè)文件解壓壓縮框架,從使用者的角度出發(fā),只需關(guān)注發(fā)送給框架一個(gè)解壓請(qǐng)求,框架完成復(fù)雜文件的解壓操作,并且在適當(dāng)?shù)臅r(shí)候通知給是哦難過(guò)者,如解壓完成、解壓出錯(cuò)等。在框架內(nèi)部去構(gòu)建對(duì)象的關(guān)系,通過(guò)抽象讓其更為健壯、便于更改。其次是API的說(shuō)明文檔。
轉(zhuǎn)自知乎:https://zhuanlan.zhihu.com/p/33695465