iOS 類和isa的面試題分析

2021-10-09 11:51:58 字數 4433 閱讀 8615

看面試題前面,我們首先來了解幾個概念:

第乙個面試題:方法的歸屬問題

@inte***ce lgperson : nsobject-(

void

)sayhello;+(

void

@end

@implementation lgperson-(

void

)sayhello+(

void

nslog()

;}@end

然後我們先寫幾個函式:

void

lgobjc_copymethodlist

(class pclass)

free

(methods)

;}

void

lginstancemethod_classtometaclass

(class pclass)

void

lgclassmethod_classtometaclass

(class pclass)

void

lgimp_classtometaclass

(class pclass)

我們在mian.m函式中的幾個函式去驗證:

int

main

(int argc,

const

char

* ar**)

return0;

}

執行完之後我們會得到以下結果:

下面我們乙個個分析這是是四個函式

我們發現這個函式只列印出來了sayhello,說明這個pclass這個類裡面只包含- (void)sayhello這個例項方法。

lgclassmethod_classtometaclass函式解析:

我們先了解下class_getclassmethod:根據蘋果文件我們知道他的主要作用是:返回給定類的指定的類方法,如果在類或者父類中都找到這個類方法,就返回null。我們看下原始碼:

method class_getclassmethod

(class cls, sel sel)

class getmeta()

imp class_getmethodimplementation

(class cls, sel sel)

return imp;

}

經過原始碼的檢視,我們發現這個函式主要是返回乙個返回方法的具體實現

如果方法sel已經實現了,則返回乙個方法實現的函式指標

如果方法sel沒有實現或者這個方法在類或者元類中找不到,則返回乙個屬於訊息**機制的乙個函式指標

第二個面試題:
bool re1 =

[(id)

[nsobject class] iskindofclass:

[nsobject class]];

// bool re2 =

[(id)

[nsobject class] ismemberofclass:

[nsobject class]];

// bool re3 =

[(id)

[lgperson class] iskindofclass:

[lgperson class]];

// bool re4 =

[(id)

[lgperson class] ismemberofclass:

[lgperson class]];

//nslog

(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n"

,re1,re2,re3,re4)

; bool re5 =

[(id)

[nsobject alloc] iskindofclass:

[nsobject class]];

// bool re6 =

[(id)

[nsobject alloc] ismemberofclass:

[nsobject class]];

// bool re7 =

[(id)

[lgperson alloc] iskindofclass:

[lgperson class]];

// bool re8 =

[(id)

[lgperson alloc] ismemberofclass:

[lgperson class]];

//nslog

(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n"

,re5,re6,re7,re8)

;

對上面的面試題,我們進過列印會發現他們的結果是:re1、re2、re3、re4 分別是1、0、0、0re5、re6、re7、re8 分別是1、1、1、1,但是為什麼會出現這個結果,我們來驗證下,首先我們先看看這幾個方法的含義是啥:

這個面試題主要是考察iskindofclassismemberofclass在類方法的呼叫和例項方法的呼叫中,re1、re2、re3、re4類方法呼叫re5、re6、re7、re8例項方法呼叫,我們首先看下這兩個函式的原始碼

+

(bool)iskindofclass:

(class)cls

return no;}-

(bool)iskindofclass:

(class)cls

return no;

}

解讀方法:

+

(bool)ismemberofclass:

(class)cls

-(bool)ismemberofclass:

(class)cls

解讀方法:

警告:這裡的原始碼有個坑點我們要注意下: 我們打斷點除錯的時候,發現ismemberofclass類方法和例項方法走流程的時候會很正常的走到原始碼中

但是iskindofclass類方法和例項方法卻不會走到原始碼中,反而會走到objc_opt_iskindofclass方法的原始碼中,這是為什麼呢?

這是因為llvm中編譯時對其進行了優化處理.

解讀上面的面試例子:

傳入類lgperson,物件是lgperson,根據ismemberofclass得知,物件lgperson的元類是元類 lgperson,發現傳入類和物件的元類不一樣,返回0

傳入類nsobject根類,物件是nsobject,根據iskindofclass這個例項方法的繼承鏈:物件父類 --> 根類(nsobject) --> nil,發現物件的的根類傳入類相等,所以返回1

流程圖

iOS 面試題(六)

回答person的retaincount值,並解釋為什麼 person per person alloc init self.person per 1 或者2 看物件用什麼屬性修飾,person類物件在建立的時候引用計數加1,若用 assign類不會使引用計數加1的屬性修飾 person的retai...

iOS 面試題(九)

objective c有私有方法麼?私有變數呢?如多沒有的話,有沒有什麼代替的方法?oc中沒有私有方法,有私有變數 私有方法可以用category 類目 extension 延展 來代替 2 import include和 class有什麼區別 include 用於系統自帶的標頭檔案的引用,編譯器會...

iOS 面試題(十)

如何將產品進行多語言發布?在工程infoplist.strings中新增發布時需要的語言,並在 建立 strings 檔案進行 字串 和其他檔案的多語言處理 2 如何將敏感字變成 訪問敏感字的陣列 nsmutablearray array nsmutablearray alloc init 向敏感字...