ios面試題(整理)
- ios常用的設(shè)計(jì)模式有哪些?
MVC模式针余、委托模式毙玻、觀察者模式(kvo、kvc土居、通知機(jī)制)、單例模式.
我對觀察者的理解:就好像一個(gè)人在炒股,一夜暴富,他的狀態(tài)從貧窮變?yōu)楦挥?他通知他的親朋好友,然后他的親朋好友根據(jù)自身要求改變.
一個(gè)對象在自身狀態(tài)發(fā)生改變后,通知監(jiān)視他的對象,監(jiān)視他的對象根據(jù)自身?xiàng)l件發(fā)生改變.
對通知機(jī)制的理解:就相當(dāng)于我們平時(shí)發(fā)說說,將我們當(dāng)前的狀態(tài)發(fā)布在QQ空間,對你感興趣的人,會將你設(shè)為特別關(guān)注,只要你發(fā)動態(tài),那個(gè)人就會收到通知.
一個(gè)對象將他的狀態(tài)發(fā)布在通知里面,對他感興趣的對象,可以申請?jiān)谔囟ㄍㄖl(fā)布時(shí)接受這個(gè)通知.
- kvc的底層實(shí)現(xiàn)原理是什么?
Kvc在單類情況下,用setValue:forkey(相當(dāng)于set) 和valueForKey(get)訪問屬性.在類嵌套下,用setValue: forKeyPath(set)和valueForKeyPath(get)訪問.如果訪問不到,就會報(bào)出setValue:forUndleKey這個(gè)錯(cuò)誤.
在ios開發(fā)中,我們可以通過set和get方法來訪問對象的屬性,若一個(gè)對象的屬性沒有提供get和set方法,外界就失去了訪問這個(gè)屬性的訪問渠道,針對這種情況,ios提供了kvc機(jī)制,可以間接訪問對象的屬性.操作屬性,獲取key路徑,處理不存在的key.
Kvc是一種通過對象的屬性名稱,將其作為key,簡接的訪問該屬性的機(jī)制.假設(shè)有一個(gè)Person類,該類有一個(gè)name屬性,對于setValue:屬性值 forKey:@”name”這句代碼,底層的執(zhí)行機(jī)制如下:
(1) 程序會優(yōu)先考慮setName方法,代碼會通過setter方法完成設(shè)置.
(2) 若Person類沒有name屬性的setter方法,kvc機(jī)制會搜索該類中名稱為_name的成員變量,無論成員變量在類的接口部分定義,還是在類的實(shí)現(xiàn)部分定義,甚至用任意的訪問修飾符,底層實(shí)際上就是對名稱為_name的成員變量賦值.
(3) 若Person類中既沒有setName方法,也沒有定義名稱為_name的成員變量,那么,kvc機(jī)制就會搜索該類名字為name的成員變量,無論該成員變量是在類的接口部分定義,還是在類的實(shí)現(xiàn)部分定義,甚至是用任意的訪問修飾符修飾,這條kvc代碼底層就是對name成員變量賦值.
(4) 如果以上3條沒有找到,系統(tǒng)會執(zhí)行該對象的setValue:forUndefinedKey方法.同理,valueForKey:@”name”這句代碼也會遵循相同的方式,一步一步搜素.
- Kvo底層實(shí)現(xiàn)原理
Kvo機(jī)制是由oc強(qiáng)大的runtime所支持的,程序在運(yùn)行的過程中,系統(tǒng)會自動地通過runtime給被監(jiān)聽的對象創(chuàng)建一個(gè)子類,其名稱為”NSKVONotifying_類名稱”,并重寫該子類的set方法,在set方法調(diào)用監(jiān)聽者的observeValueForKeyPath:ofObject:change:context:方法.
單例模式:如果全局都用到了.在內(nèi)存中可以只創(chuàng)建一份,節(jié)省內(nèi)存.
類工廠方法的實(shí)現(xiàn)
(void)sharedSingleton{
Static Dispatch_once_t onceToken;
Dispatch_once (&onceToken,^{
_ShareInstance = [super allocwithZone:zone];
});
return _shareInstance;
}
//用copywithzone重寫
(void)copyWithZone:(struct_NSZone *)zone{
return_shareInstance;
}
我們?yōu)槭裁从肎CD的dispatch_once實(shí)現(xiàn)單例呢,因?yàn)镈ispatch_once有兩個(gè)參數(shù),dispatch_once_t,可以判斷線程是否被調(diào)度,保證線程安全.dispathc_block_t,保證代碼塊只被調(diào)用一次.優(yōu)點(diǎn):線程安全,很好的滿足了靜態(tài)分析器的要求,能夠自動應(yīng)用計(jì)數(shù)兼容,僅僅只需要少量的代碼.
缺點(diǎn):仍然可以運(yùn)行創(chuàng)建一個(gè)非共享的實(shí)例,可以使用alloc實(shí)例化一個(gè)對象.
Delegate傳值
兩個(gè)控制器,第一個(gè)控制器要向第二個(gè)控制器傳值,第一個(gè)控制器就需要聲明一個(gè)代理協(xié)議,把要傳遞的參數(shù)寫在協(xié)議的聲明方法里.在第一個(gè)控制器聲明里,引入@property(nonatomic,weak)id< ----delegate>delegate屬性.在實(shí)現(xiàn)文件里,需要判斷一下協(xié)議是否響應(yīng)了協(xié)議方法.
If ([_delegate isResponseSelector:@selector(_____delegate聲明的方法) ]{
};
在第二個(gè)控制器里面,實(shí)現(xiàn)聲明的代理方法.這樣就完成了傳值.