接口與API設(shè)計(jì)
第15條:用前綴避免命名空間沖突
OC沒(méi)有其他語(yǔ)言那種內(nèi)置的命名空間。所以我們起名時(shí)要避免潛在的命名沖突,否則就容易重名,而引發(fā)命名沖突(
naming clash)。Apple宣稱其保留使用所有“兩字母前綴”,所以我們一般還是三個(gè)字母開頭比較好,選擇與我們自己的公司、應(yīng)用程序或二者皆有關(guān)聯(lián)之名作為類名的前綴。
第16條:提供“全能初始化方法”
為對(duì)象提供必要信息以便其完成工作的初始化方法叫做“全能初始化方法”,也可以稱為“指定初始化方法”。
例如UITableViewCell中的初始化
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)reuseIdentifier `
再看看 UISegmentedControl和UINavigationItem的初始化,就董了。
第17條:實(shí)現(xiàn)”description“方法
平常我們自定義的類中,如果我們直接打印我們的對(duì)象它會(huì)輸出<Object:0x*****>,并不是我們要的,這樣并沒(méi)有什么用,所以當(dāng)我們重寫description的時(shí)候才可能滿足我們調(diào)試的需求。
- (NSString *)description
{
return [NSString stringWithFormat:@"%@:%@,%@",[self class],self,@"你需要的屬性"];
}
另外你也可以重寫debugDescription,再與”po“命令一起使用配合調(diào)試。
第18條:盡量使用不可變對(duì)象
簡(jiǎn)單的說(shuō),我們?cè)O(shè)計(jì)出來(lái)的類里面屬性,我們是不希望讓別人改變的,一般設(shè)置為只讀的(
read-only),如果是可變的情況下,很容易改變set的內(nèi)部結(jié)構(gòu),從而失去了固有的意義。
第19條:使用清晰而協(xié)調(diào)的命名方式
遵從Objective-C命名規(guī)范,言簡(jiǎn)意賅,不使用縮略后的類型名稱。
參照下 NSString 類的方法,你就懂了
- (BOOL)hasPrefix:(NSString *)str;
- (BOOL)hasSuffix:(NSString *)str;
- (NSString *)substringFromIndex:(NSUInteger)from;
- (NSString *)substringToIndex:(NSUInteger)to;
- (NSString *)substringWithRange:(NSRange)range;
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
- (void)deleteCharactersInRange:(NSRange)range;
- (void)appendString:(NSString *)aString;
- (void)appendFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
- (void)setString:(NSString *)aString;
第20條:對(duì)私有方法名加前綴
這樣的有助于調(diào)試,也很容易讓我們將公共方法和私有方法區(qū)分開,另外便于修改方法名。但是要注意不要但用一個(gè)下滑線做私有方法的前綴,因?yàn)檫@中做法是預(yù)留給蘋果公司的。
- (void)yp_setMyTestMethod
{
// y==我,p== private
}
- (void)_setSomeMethod
{
// 這種是蘋果公司預(yù)留,不推薦
}
第21條:理解Objective-C錯(cuò)誤類型
現(xiàn)在一般的語(yǔ)言都有異常處理機(jī)制,Objective-C也不例外。在OC中異常只用于處理嚴(yán)重錯(cuò)誤(
fatal error),出現(xiàn)”不那么嚴(yán)重的錯(cuò)誤(nonfatal error)“,它會(huì)是令方法返回nil/0,或者使用NSError,以表明有錯(cuò)誤發(fā)生。 所以我們還是需要了解下NSError。
第22條:理解NSCoping協(xié)議
在Objective-c中, 某個(gè)類遵守了NSCopying協(xié)議就代表這個(gè)類支持[obj copy]操作。在沒(méi)有實(shí)現(xiàn)NSCopying協(xié)議的情況下調(diào)用對(duì)象的copy函數(shù)則會(huì)出現(xiàn)異常。NSCopying協(xié)議只有一個(gè)函數(shù),即copyWithZone, 聲明如下 :
@protocol NSCopying
- (id)copyWithZone:(nullable NSZone *)zone;
@end
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(nullable NSZone *)zone;
@end
淺拷貝之后的內(nèi)容與原始內(nèi)容均指向相同對(duì)象;深拷貝之后的內(nèi)容所指的對(duì)象是原始內(nèi)容中相關(guān)對(duì)象的一份拷貝。用一句簡(jiǎn)單的話來(lái)說(shuō)就是淺拷貝,只是對(duì)指針的拷貝,拷貝后兩個(gè)指針指向同一個(gè)內(nèi)存空間,深拷貝不但對(duì)指針進(jìn)行拷貝,而且對(duì)指針指向的內(nèi)容進(jìn)行拷貝,經(jīng)深拷貝后的指針是指向兩個(gè)不同地址的指針。
- 若想令自己所寫的對(duì)象具有拷貝功能,需要實(shí)現(xiàn)”
NSCopying“協(xié)議。
- 如果自定義的對(duì)象分為可變與不可變版本,那么就要同時(shí)實(shí)現(xiàn)”
NSCopying“與”NSMutableCopying“協(xié)議。
協(xié)議和分類
第23條:通過(guò)委托和數(shù)據(jù)源協(xié)議進(jìn)行對(duì)象間通信
簡(jiǎn)單的說(shuō),就是多用代理進(jìn)行數(shù)據(jù)傳遞??梢詤⒄?code>UITableView的
delegate和data source進(jìn)行處理,當(dāng)然也可以直接寫一個(gè)Protocol進(jìn)行例如String進(jìn)行傳遞。
第24條:將類的實(shí)現(xiàn)代碼分散到便于管理的數(shù)個(gè)分類中
這個(gè)就是我們需要有分類的思想,通過(guò)分類機(jī)制,可以把類代碼中分成很多歌易于管理的小塊,便于單獨(dú)檢查。
第25條:總是為第三方類的分類名稱增加前綴
這個(gè)同理第15條,在我們向第三方類中添加分類時(shí),總應(yīng)給其名稱和其中的方法加上你專有的前綴,達(dá)到易于區(qū)分,避免錯(cuò)誤的目的。
第26條:勿在分類中申明屬性
因?yàn)槌恕盋lass-continuation分類“,其他分類無(wú)法向類中新增實(shí)例變量,這樣就無(wú)法把實(shí)現(xiàn)屬性所需要的實(shí)例變量合成出來(lái)。

第27條:使用”Class-continuation分類“隱藏細(xì)節(jié)
Class-continuation分類和普通的分類不同,它必須定義在其所接續(xù)的那個(gè)類的實(shí)現(xiàn)文件里。其重要之處,這是唯一能聲明。一般我們單獨(dú)建立一個(gè)自定義的
View或NSObject類中我們就常用到。
#import "TestPeople.h"
@interface TestPeople ()
// 寫你所需要的私有變量或方法
@end
@implementation TestPeople
// 實(shí)現(xiàn)
@end
第28條:通過(guò)協(xié)議提供匿名對(duì)象
我們可以用協(xié)議把自己所寫的API之中的實(shí)現(xiàn)細(xì)節(jié)隱藏起來(lái),將返回的對(duì)象設(shè)計(jì)為遵從此協(xié)議的純
id類型。這樣的話,想要隱藏的類名就不會(huì)出現(xiàn)在API之中啦。
因?yàn)橛袝r(shí)候接口的背后有多個(gè)不同的實(shí)現(xiàn)類,而你又不想指明具體使用的類,那么就要考慮這個(gè)方法啦。