年輕的時候要多看點東西,時間是非常寶貴的,不要浪費生命在無所謂的事情上,共勉
1.異常使用的場景是 當(dāng)程序發(fā)生非常嚴(yán)重崩潰的時候。在錯誤不是那么嚴(yán)重的情況下,可以指派"委托方法"來處理錯誤對象,或者也可以吧錯誤信息放在NSERROR對象中,經(jīng)過"輸出參數(shù)"返回給調(diào)用者
- 假如想讓自己所寫的對象具有拷貝功能,那么需要實現(xiàn)NSCopying協(xié)議。
- 如果自己寫的對象同時分為可變版本與不可變版本,那么就需要同時實現(xiàn)NSCopying協(xié)議與NSMutableCopying協(xié)議。
- 執(zhí)行對象拷貝的時候需要考慮應(yīng)該是深拷貝還是淺拷貝,但是大多數(shù)情況下應(yīng)該使用淺拷貝。
3.對象之間經(jīng)常需要相互通信,而通信方式有很多。OC開發(fā)者廣泛使用一種名叫“委托模式”(Delegate Pattern)的編程設(shè)計模式來實現(xiàn)對象間的通信,該模式的主旨是:定義一套接口,某對象若想接收另一個對象的委托,則需遵從此接口,以便稱為“委托對象”(delegate)。而這“另一個對象”則可以給其委托對象回傳一些信息,也可以在發(fā)生相關(guān)聯(lián)時間時通知委托對象。
此模式可以將數(shù)據(jù)與業(yè)務(wù)邏輯解耦。在Objective-C中,一般通過“協(xié)議”這項語言特性來實現(xiàn)此模式,整個Coco系統(tǒng)框架都是這么做的。如果你的代買也這樣寫,那么就能和系統(tǒng)框架很好地融合在一起了。

利用協(xié)議機(jī)制,很容易就以O(shè)bjective-C代碼實現(xiàn)此模式,代碼如下:
@protocol EOCNetworkFetcherDelegate
-(void)netWorkFetcher:(EOCNetworkFetcher*)fetcher didReceiveData:(NSData*)data;//這個EOCNetworkFetcher*參數(shù)可以高速委托對象,是誰調(diào)用它的
-(void)netWorkFetcher:(EOCNetworkFetcher*)fetcher didFailWithData:(NSError*)error;
@end
有了這個協(xié)議之后,類就可以用一個屬性來存儲委托對象了。在本例中,這個類就是EOCNetworkFetcher類:
@interface EOCNetworkFetcher :NSObject
@property (nonatomic,weak) id<EOCNetworkFetcherDelegate> delegate;
@end

為了避免循環(huán)引用,NetWorkFetcher不保留delegate屬性.
看一下EOCDataModel的實現(xiàn):
NSData *data = /*data obtained from network*/
if([_delegate respondsToSelector:@selector(networkFetcher:didReceiveData:)]){
[_delegate networkFetcher:self didReceiveData:data];
}
通過這個例子,大家應(yīng)該很容易理解此模式為何叫做“委托模式”:因為對象把應(yīng)對某個行為的責(zé)任委托給另外一個類了。
關(guān)于運(yùn)行時刻,每次都判斷respondsToSelector:@selector(xxxx)是多余的,只有第一次判斷是有用的。參考優(yōu)化辦法
【本節(jié)要點】
● 委托模式為對象提供了一套接口,使其可由此相關(guān)事件告知其他對象。
● 將委托對象應(yīng)該支持的接口定義成協(xié)議,在協(xié)議中把可能需要處理的事情定義成方法
● 當(dāng)某對象需從另一個對象中獲取數(shù)據(jù)時,可以使用委托模式。這種情境下,該模式亦稱為“數(shù)據(jù)源協(xié)議”(data source protocal)
● 若有必要,可實現(xiàn)還有位段的結(jié)構(gòu)體,將委托對象是否能夠相應(yīng)相關(guān)協(xié)議方法這一信息緩存至其中。
4.記住一條原則就可以了,如果一個類方法太多,可以將這些方法按照功能拆分成多個文件。每個文件可以看作是原來類的一個分類。如果想隱藏一個方法的實現(xiàn),那就可以在分類中實現(xiàn)一個方法,但是不在主類的頭文件中聲明即可。
5.在使用分類的時候,如果要擴(kuò)展系統(tǒng)的方法或者給第三方類添加方法,需要給創(chuàng)建的對象方法名字前面添加前綴,這樣可以避免命名沖突。保證方法調(diào)用的正確性。
6.蘋果是建議不要再分類中添加屬性,因為對象屬性的ivarsize再編譯階段大小就是確定的。但是不排除一些特定業(yè)務(wù)場景下面,確實需要添加一些屬性,這樣可以使用關(guān)聯(lián)對象來做,前面也提到過,不做敘述。
7.主要講的是擴(kuò)展的概念,也叫做匿名的分類。擴(kuò)展(EXTENSION)不能單獨創(chuàng)建一個文件,他是依附在要擴(kuò)展的主類的.m文件中的。擴(kuò)展的主要功能有:
- 向原有的類中新增一個實例變量
- 如果想讓一個變量對外只讀,對內(nèi)可讀可寫,可以再.h文件中聲明為readonly,在.m文件中設(shè)置為readwrite。
- 再擴(kuò)展中聲明一個私有的方法
- 或者隱藏這個類實現(xiàn)的協(xié)議
總得來說,類擴(kuò)展主要是一個私有變量,私有方法,隱藏類信息的地方
8.通過協(xié)議來提供匿名對象。
協(xié)議定義了一系列方法,遵從此協(xié)議的對象應(yīng)該實現(xiàn)它們。于是,我們可以用協(xié)議把自己寫的API之中的實現(xiàn)細(xì)節(jié)隱藏起來,將返回的對象涉及位遵從此協(xié)議的純id類型。這樣的話,想要隱藏的類名就不會出現(xiàn)在API之中了。
此概念經(jīng)常稱為:“匿名對象”(anonymous object),這與其他語言的“匿名對象”不同。
@property (nonatomic,weak)id<EOCDelegate> delegate;
由于該屬性的類型是id<EOCDelegate>,所以實際上任何類型的對象都能充當(dāng)這一屬性,即便該類不繼承自NSObject也可以,只要遵循EOCDelegae協(xié)議就行。
NSDictionary也能實際說明這一概念,在字典中,鍵的標(biāo)準(zhǔn)內(nèi)存管理語義是“設(shè)置時拷貝”,而值的語義是“設(shè)置時保留”。因此在可變版本的字典中,設(shè)置鍵值對所用的方法的簽名是:
-(void) setObject:(id)object forKey:(id<NSCopying>)key;
表示鍵的哪個參數(shù)類型位id<NSCopying>,作為參數(shù)值的對象,它可以是任意類型,只要遵從NSCopying協(xié)議就好,這樣的話,就能向該對象發(fā)送拷貝消息了。這個key參數(shù)可以視為匿名對象。與delegate一樣
數(shù)據(jù)案例,數(shù)據(jù)庫連接(database connection)的程序也用這個思路,以匿名對象來表示從另一個庫中返回的對象。對于處理連接哪個類,你也許不想讓萬人知道。如果沒有辦法令其繼承字同一個基類,那么就得返回對下你跟遵從此協(xié)議:
@protocol EOCDatabaseConnection
-(void) connect;
-(void)disconnect;
-(void)isConnected;
-(NSArray*)performQuery:(NSString*)query;
@end;
然后,就可以用“數(shù)據(jù)庫處理器”單例來提供數(shù)據(jù)庫連接了。這個單例的接口可以寫成
@protocol EOCDatabaseConnection
@interface EOCDatabaseManger:NSObject
+(id)sharedInstance;
-(id<EOCDatabaseConnection>) connectionWithIdentifier:(NSString*)identifier;
@end;
這樣的話,處理數(shù)據(jù)庫連接所用的類名稱幾UI不會泄露了。
有時對象類型并不重要,重要的是對象有沒有實現(xiàn)某些方法。在次情況下,也可以是使用“匿名類型”(anonymous type)來表達(dá)這一概念。
CoreData框架里也有這種用法。查詢CoreData數(shù)據(jù)庫所得的結(jié)果由名叫NSFetchedResultsContrller的類來處理,如果有需要,處理時還會把數(shù)據(jù)分區(qū)。在負(fù)責(zé)處理查詢結(jié)果的控制器中,有個section屬性,用以表示數(shù)據(jù)分區(qū)。此屬性是個數(shù)組,但其中的對像沒有指明具體類型,只是說這些對象遵從了NSFetchedResultsSectionInfo協(xié)議。下面代碼通過控制器來獲取數(shù)據(jù)分區(qū)信息:
NSFetchedResultsController * controller = /*some controller*/;
NSUInteger section = /*section index to query*/
NSArray *sections = controller.sections;
id<NSFetchedResultsSectionInfo> sectionInfo = sections[section];
NSUInteger numberOfObjects = sectionInfo.numberOfObjects;
sectionInfo 是個匿名對象。
【本節(jié)要點】
● 協(xié)議可在某種程度上提供匿名類型。具體的對象類型可以淡化成遵從某協(xié)議的id類型,協(xié)議里規(guī)定了對象所應(yīng)實現(xiàn)的方法。
● 使用匿名對象來隱藏類型名稱(或類名)
● 如果居室類型不重要,重要的是對象能夠響應(yīng)特定方法,那么可以是使用匿名對象來表示。
9.自動引用計數(shù)。沒什么可說的,摘抄一下總結(jié)
- 引用計數(shù)機(jī)制通過遞增或者遞減的計數(shù)器來管理內(nèi)存。對象創(chuàng)建好之后,其保留計數(shù)至少為1。假如保留計數(shù)為正,那么對象會繼續(xù)存活。當(dāng)保留計數(shù)降到0的時候,對象被銷毀
- 在對象的聲明周期中,其余對象通過引用來保留或者釋放對象。保留與釋放的操作分別會遞增或者遞減保留計數(shù)
10.沒什么可講的 主要說的是ARC做的一些事情,替我們手動插入 retain release autorelease等等