《禪與 Objective-C 編程藝術(shù) 》閱讀筆記

原文:禪與 Objective-C 編程藝術(shù)

條件語(yǔ)句

總是要用大括號(hào)

尤達(dá)表達(dá)式

不推薦

nil 和 BOOL

不要直接把對(duì)象跟nil或YES,NO比較褒纲,用 if(!xx)來(lái)即可

黃金大道

即不要嵌套if語(yǔ)句,可以使用return語(yǔ)句避免增加循環(huán)的復(fù)雜度

即推薦:

- (void)someMethod {
  if (![someOther boolValue]) {
      return;
  }

  //Do something important
}

不推薦

- (void)someMethod {
  if ([someOther boolValue]) {
    //Do something important
  }
}

其中有句原話是:

在使用條件語(yǔ)句編程時(shí)双抽,代碼的左邊距應(yīng)該是一條“黃金”或者“快樂(lè)”的大道。

對(duì)黃金大道這個(gè)比喻不理解闲礼,不明白黃金大道的在這里的比喻牍汹。
但是上面的例子是比較清晰的。

復(fù)雜的表達(dá)式

if中的復(fù)雜表達(dá)式柬泽,提取出來(lái)賦值給BOOL慎菲,使之更清晰 。

BOOL nameContainsSwift  = [sessionName containsString:@"Swift"];
BOOL isCurrentYear      = [sessionDateCompontents year] == 2014;
BOOL isSwiftSession     = nameContainsSwift && isCurrentYear;

if (isSwiftSession) {
    // Do something very cool
}

三元運(yùn)算符

三元運(yùn)算符里的子句锨并,應(yīng)該也只是求值后的變量露该,不要直接用復(fù)雜的句子。

推薦

result = a > b ? x : y;

不推薦

result = a > b ? x = c > d ? c : d : y;

另外第煮,推薦更靈活地表達(dá)方式:

result = object ? : [self createObject];

不推薦

result = object ? object : [self createObject];

錯(cuò)誤處理

有些方法通過(guò)參數(shù)返回 error 的引用解幼,使用這樣的方法時(shí)應(yīng)當(dāng)檢查方法的返回值,而非 error 的引用包警。

推薦:

  NSError *error = nil;
  if (![self trySomethingWithError:&error]) {
      // Handle Error
  }

此外书幕,一些蘋(píng)果的 API 在成功的情況下會(huì)對(duì) error 參數(shù)(如果它非 NULL)寫(xiě)入垃圾值(garbage values),所以如果檢查 error 的值可能導(dǎo)致錯(cuò)誤 (甚至崩潰)揽趾。

Case語(yǔ)句

switch語(yǔ)句里是枚舉變量時(shí)台汇,建議不要用default,因?yàn)楫?dāng)枚舉增加時(shí),這些switch語(yǔ)句會(huì)收到警告

使用枚舉變量時(shí)篱瞎,建議使用新的宏- NS_ENUM()

命名

通用的約定

駝峰法命名

內(nèi)存管理規(guī)則:

You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).

常量

駝峰法苟呐,類(lèi)名做前綴,盡量用常量類(lèi)型少用宏

方法

  • 方法名與方法類(lèi)型 (-/+ 符號(hào))之間應(yīng)該以空格間隔
  • 方法段之間也應(yīng)該以空格間隔(以符合 Apple 風(fēng)格)
  • 參數(shù)前應(yīng)該總是有一個(gè)描述性的關(guān)鍵詞俐筋。盡可能少用 "and" 這個(gè)詞

字面值

不推薦[@[] mutableCopy]這種寫(xiě)法牵素。

類(lèi)

類(lèi)名

  • 類(lèi)名應(yīng)該以三個(gè)大寫(xiě)字母作為前綴
  • 當(dāng)你創(chuàng)建一個(gè)子類(lèi)的時(shí)候,你應(yīng)該把說(shuō)明性的部分放在前綴和父類(lèi)名的在中間澄者。如有一個(gè) ZOCNetworkClient 類(lèi)笆呆,子類(lèi)的名字會(huì)是ZOCTwitterNetworkClient

Initializer 和 dealloc

  • dealloc函數(shù)應(yīng)該放在文件的最前面,init方法跟在后面粱挡。
  • allocinit方法解釋赠幕。

Designated 和 Secondary 初始化方法

  • 一個(gè)類(lèi)應(yīng)該有且只有一個(gè) designated 初始化方法
  • 子類(lèi)的Designated Initializer應(yīng)該調(diào)用父類(lèi)的Designated Initializer方法。
  • NS_DESIGNATED_INITIALIZER來(lái)指定為Designated Initializer(方法后加上該宏)询筏。
  • Secondary Initializer應(yīng)該調(diào)用Designated Initializer
  • 初始化方法返回參數(shù)用instancetype替換id
  • 類(lèi)簇 (class cluster)的解釋
  • 單例用dispatch_once()替代@synchronized

屬性

  • 命名用小寫(xiě)字母開(kāi)頭的駝峰命名
  • 在init方法里要直接用實(shí)例變量榕堰,不要用set/get方法訪問(wèn)屬性變量。因?yàn)樽宇?lèi)可能重載屬性變量嫌套。
  • 用點(diǎn)語(yǔ)法
  • 屬性的參數(shù)應(yīng)該按照下面的順序排列: 原子性逆屡,讀寫(xiě) 和 內(nèi)存管理
  • NSString,NSArray,NSURLRequest等有可變對(duì)象的類(lèi)圾旨,盡量用copy,防止用strong指向可變子類(lèi)魏蔗,導(dǎo)致值被修改出現(xiàn)問(wèn)題
  • 用懶加載(Lazy Loading)時(shí)砍的,注意副作用,如get方法里修改了一些類(lèi)的全局變量莺治,導(dǎo)致加載時(shí)機(jī)不同出現(xiàn)問(wèn)題

方法

  • 用斷言NSAssert()NSParameterAssert()拋參數(shù)異常
  • 私有變量和私有方法不要用_前綴挨约,蘋(píng)果已保留該前綴

相等性

當(dāng)你要實(shí)現(xiàn)相等性的時(shí)候記住這個(gè)約定:你需要同時(shí)實(shí)現(xiàn)isEqual 和 hash方法。如果兩個(gè)對(duì)象是被isEqual認(rèn)為相等的产雹,它們的 hash 方法需要返回一樣的值诫惭。但是如果 hash 返回一樣的值,并不能確保他們相等蔓挖。

Categories

category里的方法應(yīng)該用自己的小寫(xiě)前綴加下劃線夕土,如- (id)zoc_myCategoryMethod

Protocols

用協(xié)議提高代碼的復(fù)用性

NSNotification

通知名應(yīng)該用類(lèi)名做前綴,用一個(gè) Did/Will 這樣的動(dòng)詞以及用 "Notifications" 后綴瘟判。如

// Foo.h
extern NSString * const ZOCFooDidBecomeBarNotification

// Foo.m
NSString * const ZOCFooDidBecomeBarNotification = @"ZOCFooDidBecomeBarNotification";

美化代碼

  • 空格怨绣,這里說(shuō)用四個(gè)空格替代TAB,但是一般文章都是推薦用TAB拷获,因?yàn)榭梢愿鶕?jù)編譯的設(shè)定而改變篮撑,所以這里存疑
  • 方法的大括號(hào)和其他的大括號(hào)(if/else/switch/while 等) 總是在同一行開(kāi)始
  • 方法之間要有空行
  • 參數(shù)換行

代碼組織

  • 善用代碼塊{}

  • 方法用#pragma mark -組織分離

  • 當(dāng)用performSelector調(diào)用方法在ARC出現(xiàn)警告時(shí),可用#pragma clang diagnostic去除警告匆瓜,代碼示例:

      #pragma clang diagnostic push
      #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
      
      [myObj performSelector:mySelector withObject:name];
      
      #pragma clang diagnostic pop
    
  • 忽視未讀變量的方法:#pragma unused (foo)(如果foo變量未使用赢笨,用該方法不提示警告)

  • 注釋分兩種///** */非公開(kāi)驮吱、很短茧妒、顯而易見(jiàn)的函數(shù)一般用//,其它和對(duì)外暴露的一般用/** */

對(duì)象間的通訊

  • Block,這里說(shuō)下“在 block 外定義一個(gè) __weak 的 引用到 self左冬,并在 block 內(nèi)部通過(guò)這個(gè)弱引用定義一個(gè) __strong 的引用桐筏。”的情況拇砰。這種一般是需要持有self梅忌,但是又為了避免retain circle的情況。block內(nèi)的self強(qiáng)引用是Block執(zhí)行時(shí)創(chuàng)建的除破,
    示例代碼如下:

      @property (nonatomic,strong) NSString *testString;
      @property (nonatomic,copy) void(^BlockTest)();
    
    
      self.testString = @"testststs";
      __weak typeof(self)weakSelf = self;
      self.BlockTest = ^(){
          __strong typeof(self)strongSelf = weakSelf;
          NSLog(@"%@",strongSelf.testString);
      };
      
      self.BlockTest();
    

注:weakSelf是為了block不持有self牧氮,避免循環(huán)引用,而再聲明一個(gè)strongSelf是因?yàn)橐坏┻M(jìn)入block執(zhí)行皂岔,就不允許self在這個(gè)執(zhí)行過(guò)程中釋放蹋笼。block執(zhí)行完后這個(gè)strongSelf會(huì)自動(dòng)釋放展姐,沒(méi)有循環(huán)引用問(wèn)題躁垛。

  • 多重委托

面向切面編程

AOP剖毯,面向切面編程,統(tǒng)計(jì)與日志就是一個(gè)完美的例子教馆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逊谋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子土铺,更是在濱河造成了極大的恐慌胶滋,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悲敷,死亡現(xiàn)場(chǎng)離奇詭異究恤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)后德,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)部宿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人瓢湃,你說(shuō)我怎么就攤上這事理张。” “怎么了绵患?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵雾叭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我落蝙,道長(zhǎng)织狐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任筏勒,我火速辦了婚禮赚瘦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奏寨。我一直安慰自己起意,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布病瞳。 她就那樣靜靜地躺著揽咕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪套菜。 梳的紋絲不亂的頭發(fā)上亲善,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音逗柴,去河邊找鬼蛹头。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的渣蜗。 我是一名探鬼主播屠尊,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耕拷!你這毒婦竟也來(lái)了讼昆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤骚烧,失蹤者是張志新(化名)和其女友劉穎浸赫,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體赃绊,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡既峡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碧查。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涧狮。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖么夫,靈堂內(nèi)的尸體忽然破棺而出者冤,到底是詐尸還是另有隱情,我是刑警寧澤档痪,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布涉枫,位于F島的核電站,受9級(jí)特大地震影響腐螟,放射性物質(zhì)發(fā)生泄漏愿汰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一乐纸、第九天 我趴在偏房一處隱蔽的房頂上張望衬廷。 院中可真熱鬧,春花似錦汽绢、人聲如沸吗跋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)跌宛。三九已至,卻和暖如春积仗,著一層夾襖步出監(jiān)牢的瞬間疆拘,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工寂曹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哎迄,地道東北人回右。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像漱挚,于是被迫代替她去往敵國(guó)和親翔烁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容