iOS面試題總結(一)

2021-10-08 21:04:43 字數 4089 閱讀 4679

1.為什麼不能給類別category 新增成員變數?extension呢?

2.iskindofclass: 和 -ismemberofclas區別?

3.weak的實現原理

4.理解 [self class] 與 [super class] ?

5.ios中的記憶體管理機制

6.block如何訪問外部變數? 下劃線__block的作用? 如何防止迴圈引用?

7.block迴圈引用問題

(1).為什麼msonry不會迴圈引用?

(2).weakself、strongself結合使用

8.深拷貝與淺拷貝

9.kvo實現原理

10.runtime的原理及實際使用場景講解

1.為什麼不能給類別category 新增成員變數?extension呢?

分類並不會改變原有類的記憶體分布的情況,它是在執行期間決定的,此時記憶體的分布已經確定,若此時再新增例項會改變記憶體的分布情況,這對編譯性語言是災難,是不允許的。

category 是基於執行時的:

typedef struct category_t  category_t;
結構體中並沒有成員變數這個list,所以無法在category新增成員變數,新增屬性是可以的,但是不會生成新增屬性的getter和setter方法,所以,儘管新增了屬性,也無法使用點語法呼叫getter和setter方法,但你可以使用執行時實現關聯物件並可以引用。

反觀擴充套件(extension),作用是為乙個已知的類新增一些私有的資訊,必須有這個類的原始碼,才能擴充套件,它是在編譯器生效的,所以能直接為類新增屬性或者例項變數。

category跟extension最大的區別在於生效時間不一樣,category在執行時生效,而extension在編譯時生效

2.iskindofclass: 和 -ismemberofclas區別?

iskindofclass來確定乙個物件是否是乙個類的成員,或者是派生自該類的成員。

ismemberofclass只能確定乙個物件是否是當前類的成員。

3.weak的實現原理

weak是runtime維護了乙個hash(雜湊)表,用於儲存指向某個物件的所有weak指標。weak表其實是乙個hash(雜湊)表,key是所指物件的位址,value是weak指標的位址(這個位址的值是所指物件指標的位址)陣列。

物件準備釋放時,呼叫cleardeallocating函式。cleardeallocating函式首先根據物件位址獲取所有weak指標位址的陣列,然後遍歷這個陣列把其中的資料設為nil,最後把這個entry從weak表中刪除,最後清理物件的記錄。

a.x = b;

__weak b.y = a;

當a釋放時,會根據a的位址獲取所有弱引用它的指標的位址(如b.y),把它置為nil。

4.理解 [self class] 與 [super class] ?

我們知道實際上在ios中,對方法的呼叫是通過傳送訊息來完成的。也就是說使用 [self class] 時,會使用obj_msgsend(id thereceiver, sel selector, ...)函式向receiver來傳送訊息。而使用 [super class] 時,會使用obj_msgsendsuper(...)函式向receiver來傳送訊息。

————————————————

@implementation son : father 

- (id)init

return self;

} @end

上邊**會輸出什麼,為什麼

簡單來說,self和super都是指向當前例項的,不同的是,[self class]會在當前類的方法列表中去找class這個方法,[super class]會直接開始在當前類的父類中去找calss這個方法,兩者在找不到的時候,都會繼續向祖先類查詢class方法,最終到nsobject類。那麼問題來了,由於我們在father和son中都沒有去重寫class這個方法,最終自然都會去執行nsobject中的class方法,結果也自然應該是一樣的。

至於為什麼是son,我們可以看看nsobject中class的實現:

-(class)class
5.ios中的記憶體管理機制

為了管理所有物件的引用計數和weak指標,蘋果建立了乙個全域性的sidetables,雖然名字後面有個"s"不過他其實是乙個全域性的hash表,裡面的內容裝的都是sidetable結構體而已。它使用物件的記憶體位址當它的key。管理引用計數和weak指標就靠它了。

.png

6.block如何訪問外部變數? 下劃線__block的作用? 如何防止迴圈引用?

7.block迴圈引用問題

(1).為什麼msonry不會迴圈引用?

檢視masonry原始碼可以看到究竟:msonry中設定布局的方法中的block物件並沒有被view所引用,而是直接在方法內部同步執行,執行完以後block將釋放,其中捕捉的外部變數的引用計數也將還原到之前。

(2).weakself、strongself結合使用

使用weakself結合strongself的情況下,能夠避免迴圈引用,也不會造成提前釋放導致block內部**無效(野指標問題)

_person1 = [[person alloc] init];

_person2 = [[person alloc] init];

_person2.name = @"張三";

__weak __typeof(self) weakself = self;

_person1.block = ^);

};

8.深拷貝與淺拷貝

淺拷貝就是拷貝之後,並沒有真正的複製,而是複製物件和原物件都指向同乙個位址

深拷貝是真正的複製了乙份,複製的物件只想新的位址

9.kvo實現原理

當某個類的物件屬性第一次被觀察時,系統就會在執行期動態地建立該類的乙個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法。派生類在被重寫的setter方法內實現真正的通知機制。

當觀察物件a時,kvo機制動態建立乙個新的名為nskvonotifying_a的新類,該類整合字物件a的本類,且kvo為nskvonotifying_a重寫觀察屬性的setter方法,setter方法會負責在呼叫元setter方法之前和之後,通知所有觀察物件屬性值的更改情況。

被觀察屬性發生改變之前,willchangevalueforkey:被呼叫,通知系統該keypath的屬性值即將變更;當改變發生後,didchangevalueforkey:被呼叫,通知系統該keypath的屬性值已經變更;之後,observevalueforkey:ofobject:context:也會被呼叫。且重寫觀察屬性的setter方法這種繼承方式的注入是在執行時而不是編譯時實現的。

10.runtime的原理及實際使用場景

主動使用

1.字典轉模型

2.給分類屬性新增get,set方法

3.方法交換swizzling

4.設定uitextfield佔位文字的顏色

···隱式呼叫

1.kvo與kvc的實現。

2.記憶體管理,weak表的維護。

···

iOS 面試題總結

基礎但是重要 1,static 關鍵字至少有下列 n個作用 1 函式體內 static 變數的作用範圍為該函式體,不同於 auto 變數,該變數的記憶體只被分配一次,因此其值在下次呼叫時仍維持上次的值 2 在模組內的 static 全域性變數可以被模組內所用函式訪問,但不能被模組外其它函式訪問 3 ...

iOS面試題 一

圖中包含的設計模式 delegate 模式 notification kvo 觀察者模式 target action 命令模式 mvc 中介者模式 內建了策略模式 裝置並不在開發者賬號裡 有 些閃退,像ios10的時候,要我們加的那個訪問許可權,如相機的訪問,就是在plist 檔案 面加上.清 快取...

iOS面試題總結 (二)

動態繫結 程式直到執行時才知道執行哪個方法,動態繫結需要做的,即就是在例項所屬類確定後,將某些屬性和方法繫結到例項上。sel是類方法方法的指標,他就相當於c語言中的中函式指標。sel class func selector oc類裡面的方法都是被轉換成sel變數進行儲存的,當類宣告乙個物件,物件呼叫...