Chapter 4. Protocols and Categories
<br />
Item 23: Use Delegate and Data Source Protocols for Inter-object Communication
<br />
這一節(jié)講了delegate的原理和使用場景。
大部分內(nèi)容我都比較熟悉,常寫常用片林,就不記筆記了依沮。這里只記一下最后提到了一塊用bitfield data type來定義delegate flag的內(nèi)容。這個(gè)用法沒有見過流昏,可能確實(shí)也不是很常用,文中用的詞是”is often overlooked”。
bitfield data type的聲明:
struct data {
unsigned int fieldA : 8;
unsigned int fieldB : 4;
};
這里表示fieldA有8個(gè)字節(jié)存儲(chǔ)空間缸榄,也就可以存儲(chǔ)2^8個(gè)值。如果用來做delegate flag祝拯,用于表示類有沒有相應(yīng)這個(gè)代理方法,只有響應(yīng)和沒響應(yīng)兩個(gè)情況她肯,所以1bit就夠了佳头。可以在interface里這樣寫:
@interface EOCNetworkFetcher () {
struct {
unsigned int didUpdateProgressTo : 1;
}_delegateFlags;
}
@end
在setter里賦值:
_delegateFlags.didUpdateProgressTo = [delegate respondsToSelector: @selector(networkFetcher:didUpdateProgressTo:)];
這樣當(dāng)需要檢查代理是否有響應(yīng)代理方法的時(shí)候晴氨,就不用調(diào)用respondsToSelector方法康嘉,而是直接檢查flag就好了:
if (_delegateFlags: didUpdateProgressTo){
//
}
這樣做的好處是判斷速度快,效率高籽前。需要做這樣優(yōu)化的場景是需要多次調(diào)用代理方法的時(shí)候亭珍。因?yàn)槊恳淮握{(diào)用敷钾,為了安全都要先判斷,如果不停地重復(fù)判斷肄梨,就會(huì)比較低效阻荒,這時(shí)就可以考慮用這種flag判斷來代替。
<br />
Item 24: Use Categories to Break Class Implementations into Manageable Segments
<br />
這一節(jié)講的是通過給類創(chuàng)建category來讓代碼的功能分區(qū)更清晰众羡。
在說category之前侨赡,我想先考慮一下category和inheritance怎么選擇的問題。一般來說粱侣,這兩個(gè)看上去最主要的區(qū)別是subclass可以添加新的屬性羊壹。但是在前面的<Item 10: Use Associated Objects to Attach Custom Data to Existing Classes>一節(jié)也提到了,可以用associated objects為category添加屬性齐婴,所以根據(jù)這一區(qū)別來判斷似乎也不是特別準(zhǔn)確油猫。我想應(yīng)該還是從OO的本身意義出發(fā)來想,inheritance并不是單純的“擴(kuò)展”柠偶,而是創(chuàng)建了一個(gè)新類情妖。這個(gè)新類應(yīng)該有它存在的意義。而category是真正意義上的擴(kuò)展嚣州,是針對(duì)原本的類增加功能鲫售,這些功能就是需要這個(gè)類來擁有的,而不是它的某個(gè)子集來擁有该肴。
一個(gè)類的implementation里寫了太多方法的話情竹,大多數(shù)人的習(xí)慣還是用#pragma mark -
來進(jìn)行分區(qū)。這一節(jié)提出匀哄,用category來按功能分區(qū)效果更好秦效,而且如果沒必要把分類新建文件的話,大家仍可以都放在一個(gè)文件里涎嚼,利用分類名來說明每一塊的功能阱州。
這樣做的話,第一是代碼邏輯和功能更加清晰了法梯,更加self-documenting苔货。第二是在調(diào)試的時(shí)候在調(diào)用的方法后面可以看到屬于哪個(gè)分類,易于調(diào)試定位立哑。
特別地夜惭,對(duì)于不暴露給外界的方法,可以考慮創(chuàng)建private category铛绰。
<br />
Item 25: Always Prefix Category Names on Third-Party Classes
<br />
這一節(jié)很短诈茧,說的是要給分類的分類名和分類中的方法名加上前綴。
所有需要加前綴的東西捂掰,本質(zhì)原因都是為了避免沖突曾沈。放在分類這很好理解。因?yàn)榉诸惖姆椒ê皖惐緛砭陀械姆椒ㄊ菦]有優(yōu)先級(jí)之分的鸥昏,都會(huì)出現(xiàn)在類的方法列表里塞俱。如果同一個(gè)方法定義實(shí)現(xiàn)了多次,運(yùn)行時(shí)就不會(huì)知道執(zhí)行的是其中哪個(gè)互广,導(dǎo)致很奇怪又很難發(fā)現(xiàn)的bug敛腌。
特別是當(dāng)引入了第三方的類,不太清楚其內(nèi)部實(shí)現(xiàn)的情況下惫皱,這樣的危險(xiǎn)就更大像樊。
所以需要把分類名和分類中的方法名都加上前綴,人為建立name space旅敷,來避免命名沖突造成的方法相互覆蓋生棍。