看面試題前面,我們首先來了解幾個概念:
第乙個面試題:方法的歸屬問題
@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、0
re5、re6、re7、re8 分別是1、1、1、1
,但是為什麼會出現這個結果,我們來驗證下,首先我們先看看這幾個方法的含義是啥:
這個面試題主要是考察iskindofclass
和ismemberofclass
在類方法的呼叫和例項方法的呼叫中,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 向敏感字...