天天看點

OC面試題[搜集]

淺複制和深複制的差別?//淺拷貝和深拷貝

答案:

淺層複制(copy):隻複制指向對象的指針,而不複制引用對象本身。//通過對象的指針來通路這個對象

深層複制(mutableCopy):複制引用對象本身

意思就是有個A對象,複制一份後得到A_copy對象後,對于淺複制來說,A和A_copy指向的是同一個記憶體資源,複制的隻不過是是一個指針,對象本身資源

還是隻有一份,那如果我們對A_copy執行了修改操作,那麼發現A引用的對象同樣被修改,這其實違背了我們複制拷貝的一個思想。深複制就好了解了,記憶體中存在了

兩份獨立對象本身。//當修改A時,A copy不變。

打個比喻:1、淺拷貝就是:你挂了,你媽媽喊你回家吃飯時找不到人了,她很傷心。2、深拷貝就是:你克隆了一個你自己:你挂了、你兄弟還在,你媽媽喊你回家吃飯時能找到人。是以、孩子,安全起見、深拷貝吧,記得記憶體管理就是了。

類别的作用?繼承和類别在實作中有何差別?

答案:category 可以在不獲悉,不改變原來代碼的情況下往裡面添加新的方法,隻能添加,不能删除修改。// category:類、種類

并且如果類别和原來類中的方法産生名稱沖突,則類别将覆寫原來的方法,因為類别具有更高的優先級。//類别跟類的優先級

類别主要有3個作用:

(1)将類的實作分散到多個不同檔案或多個不同架構中。

(2)建立對私有方法的前向引用。

(3)向對象添加非正式協定。

 繼承可以增加,修改或者删除方法,并且可以增加屬性。

//非正式協定:是使用類别category來實作,非正式協定是NSObject的一個類别,這樣任何類的對象都可以作為委托對象來使用,它可以列出對象能夠執行的所有方法,這樣用來實作委托, 我們可以使用選擇器來判斷該非正式協定中是否有這個方法。

正式協定:是一個命名的方法清單,與非正式協定相比不同的是,它要求顯示的采用協定,采用協定的方法是在類的@interface聲明中列出協定的名稱,此時,實作協定的類應該遵守協定,承諾實作協定中的所有方法。

3 類别和類擴充的差別。

 答案:category和extensions的不同在于 後者可以添加屬性。另外後者添加的方法是必須要實作的。

extensions可以認為是一個私有的Category。

4. oc中的協定和java中的接口概念有何不同?

答案:OC中的代理有2層含義,官方定義為 formal和informal protocol。前者和Java接口一樣。

informal protocol中的方法屬于設計模式考慮範疇,不是必須實作的,但是如果有實作,就會改變類的屬性。

其實關于正式協定,類别和非正式協定我很早前學習的時候大緻看過,也寫在了學習教程裡

“非正式協定概念其實就是類别的另一種表達方式“這裡有一些你可能希望實作的方法,你可以使用他們更好的完成工作”。

這個意思是,這些是可選的。比如我門要一個更好的方法,我們就會申明一個這樣的類别去實作。然後你在後期可以直接使用這些更好的方法。

這麼看,總覺得類别這玩意兒有點像協定的可選協定。"

現在來看,其實protocal已經開始對兩者都統一和規範起來操作,因為資料中說“非正式協定使用interface修飾“,

現在我們看到協定中兩個修飾詞:“必須實作(@requied)”和“可選實作(@optional)”。

5.什麼是KVO 和 KVC?

答案:kvc:鍵 - 值編碼是一種間接通路對象的屬性使用字元串來辨別屬性,而不是通過調用存取方法,直接或通過執行個體變量通路的機制。//KVC運用了一個isa-swizzling技術。isa-swizzling就是類型混合指針機制。KVC主要通過isa-swizzling,來實作其内部查找定位的。isa指針,就是is a kind of的意思,指向維護分發表的對象的類。該分發表實際上包含了指向實作類中的方法的指針,和其它資料。

kvo(Key-Value Observing):鍵值觀察機制,他提供了觀察某一屬性變化的方法,極大的簡化了代碼。

用過的一個地方是對于按鈕點選變化狀态的的監控。

比如我自定義的一個button。   //當屬性改變時KVO回提供自動的消息通知。每次屬性改變了就會發送消息通知。這是因為當這個方案已經被明确定義,獲得架構級支援,可以友善的采用,開法人員不需要設計自己的觀察這模型,可以直接在工程裡使用。KOV的架構可以支援多個觀察者觀察同一個屬性,以及相關值。

[cpp] 

[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil]; 

#pragma mark KVO 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 

    if ([keyPath isEqualToString:@"highlighted"] ) { 

        [self setNeedsDisplay]; 

    } 

對于系統是根據keypath去取的到相應的值發生改變,理論上來說是和kvc機制的道理是一樣的。

對于kvc機制如何通過key尋找到value:

“當通過KVC調用對象時,比如:[self valueForKey:@”someKey”]時,程式會自動試圖通過幾種不同的方式解析這個調用。首先查找對象是否帶有 someKey 這個方法,如果沒找到,會繼續查找對象是否帶有someKey這個執行個體變量(iVar),如果還沒有找到,程式會繼續試圖調用 -(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實作的話,程式會抛出一個NSUndefinedKeyException 異常錯誤。

(cocoachina.com注:Key-Value Coding查找方法的時候,不僅僅會查找someKey這個方法,還會查找getsomeKey這個方法,前面加一個get,或者_someKey以及 _getsomeKey這幾種形式。同時,查找執行個體變量的時候也會不僅僅查找someKey這個變量,也會查找_someKey這個變量是否存在。)

設計valueForUndefinedKey:方法的主要目的是當你使用-(id)valueForKey方法從對象中請求值時,對象能夠在錯誤發生前,有最後的機會響應這個請求。這樣做有很多好處,下面的兩個例子說明了這樣做的好處。“

來至cocoa,這個說法應該挺有道理。

因為我們知道button卻是存在一個highlighted執行個體變量.是以為何上面我們隻是add一個相關的keypath就行了,

可以按照kvc查找的邏輯了解,就說的過去了。

6.代理的作用?

答案:代理的目的是改變或傳遞控制鍊。允許一個類在某些特定時刻通知到其他類,而不需要擷取到那些類的指針。可以減少架構複雜度。

7.oc中可修改和不可以修改類型。

答案:就是可動态添加修改和不可動态添加修改一樣。

比如NSArray和NSMutableArray。前者在初始化後的記憶體控件就是固定不可變的,後者可以添加等,可以動态申請新的記憶體空間。

8.我們說的oc是動态運作時語言是什麼意思?

答案:多态。 主要是将資料類型的确定由編譯時,推遲到了運作時。

這個問題其實淺涉及到兩個概念,運作時和多态。

運作時機制使我們直到運作時才去決定一個對象的類别,以及調用該類别對象指定方法。

多态:不同對象以自己的方式響應相同的消息的能力叫做多态。

//都用有一個相同的方法,不同的對象以自己的方式響應了相同的消息.

是以也可以說,運作時機制是多态的基礎

9.通知和協定的不同之處?

答案:協定有控制鍊(has-a)的關系,通知沒有。//通知:它可以一對多,一條消息可以發送給多個消息接受者,但是不會處理消息

控制鍊:單一擁有和可控制的對應關系。

10.關于多态性

答案:多态,子類指針可以指派給父類。

對象不僅僅可以已本身的類型存在,也可以作為其父類類型存在。 多态性是允許将父對象設定成為和一個或多個它的子對象相等的技術, 多态性使得能夠利用同一類(基類)類型的指針來引用不同類的對象,以及根據所引用對象的不同,以不同的方式執行相同的操作.

11.說說響應鍊

答案: 事件響應鍊。包括點選事件,畫面重新整理事件等。在視圖棧内從上至下,或者從下之上傳播。

12. frame和bounds有什麼不同?

答案:frame指的是:該view在父view坐标系統中的位置和大小。(參照點是父親的坐标系統)//frame:架構、結構

bounds指的是:該view在本身坐标系統中 的位置和大小。(參照點是本身坐标系統)//bounds:界限

14. NSOperation隊列

操作和操作隊列,基本可以看成java中的線程和線程池的概念。用于處理ios多線程開發的問題。

網上部分資料提到一點是,雖然是queue,但是卻并不是帶有隊列的概念,放入的操作并非是按照嚴格的先進現出。

這邊又有個疑點是,對于隊列來說,先進先出的概念是Afunc添加進隊列,Bfunc緊跟着也進入隊列,Afunc先執行這個是必然的,

但是Bfunc是等Afunc完全操作完以後,B才開始啟動并且執行,是以隊列的概念離亂上有點違背了多線程處理這個概念。

但是轉念一想其實可以參考銀行的取票和叫号系統。

是以對于A比B先排隊取票但是B率先執行完操作,我們亦然可以感性認為這還是一個隊列。

但是後來看到一票關于這操作隊列話題的文章,其中有一句提到

“因為兩個操作送出的時間間隔很近,線程池中的線程,誰先啟動是不定的。”

瞬間覺得這個queue名字有點忽悠人了,還不如pool~

綜合一點,我們知道他可以比較大的用處在于可以幫組多線程程式設計就好了。

15.是否在一個視圖控制器中嵌入兩個tableview控制器?

答案:一個視圖控制隻提供了一個View視圖,理論上一個tableViewController也不能放吧,

隻能說可以嵌入一個tableview視圖。而是宏觀的表示視圖控制者,那我們倒是可以把其看成一個視圖控制者,它可以控制多個視圖控制器,比如TabbarController

16. 一個tableView是否可以關聯兩個不同的資料源?你會怎麼處理?

答案:首先從代碼來看,資料源如何關聯上的,其實是在資料源關聯的代理方法裡實作的。

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

   if(indexPath.section == 0)

   {

   }

   if(indexPath.section == 1)

}

17. 什麼是id類型

id類型的變量可以存放任何資料類型的對象。在内部處理上,這種類型被定義為指向對象的指針,實際上是一個指向這種對象的執行個體變量的指針。

例如:id number

将number聲明為id類型的變量。可聲明的方法使其具有id類型的傳回值,如下:

-(id)newObject;(int)type;

這個程式聲明了一個名為newObject的執行個體方法,它具有名為type的單個整型參數并有id類型的傳回值。應該注意的是,對傳回值和參數類型聲明來說,id是預設的類型。

id類型是objetive-c中非常中藥店額資料類型,它是多态和動态綁定的基礎。

本文轉蓬萊仙羽51CTO部落格,原文連結:http://blog.51cto.com/dingxiaowei/1366400,如需轉載請自行聯系原作者