編寫高質(zhì)量iOS與OS X代碼的52個有效方法 Day1 2017-09-24 周日

扯會淡

? ? ?? 這周項目有點忙冠王,又要新版本的提測向挖,又要老版本適配iOS 11,確實沒有什么成段的時間可以靜下心來好好看看書哪替,只能周日的早上迎著”朝陽“看看書(其實是陰天栋荸,冷死,杭州這幾天天天下雨凭舶,I hate rainy days)晌块,最近可能會對于項目中適配iOS 11的東西,寫一篇文章(看心情吧帅霜,哈哈)匆背。

?????? 今天就先對《Effective Objective-C 2.0》的前5條做一個記錄和總結(jié)。話說這本書好像有很多人推薦身冀,看了一會覺得確實對于代碼的細節(jié)會有一個深刻的反思钝尸,我覺得是本可以細細咀嚼的書括享。

第一條:了解Objective-C語言的起源

?????? OC是基于C編寫的,這個應該大家都知道珍促,所以O(shè)C支持c铃辖,c++的混編,我個人覺得一個真正厲害的OC程序員踢星,應該對于三者混編應該有自己獨到的理解(輕噴)澳叉。但是OC跟c++,Java等面向?qū)ο蟮恼Z言有一個很大的不同沐悦,就是消息結(jié)構(gòu)機制成洗,而不是函數(shù)調(diào)用機制。

???????? //Message (OC):

???????? Object *obj = [Object new];

???????? [obj performWith:parameter and:parameter1];

???????? //Function Calling (c++)

???????? Object *obje = new Object;

???????? obj->perform(parameter,parameter1);

?????? 這在程序的編譯和執(zhí)行時有很大的區(qū)別藏否,最關(guān)鍵的一點區(qū)別是:使用消息結(jié)構(gòu)的語言瓶殃,在運行的時候,怎么執(zhí)行是由運行環(huán)境決定的副签,就是在編譯的時候遥椿,根本不關(guān)心接收消息的對象是何類型;而使用函數(shù)調(diào)用的語言淆储,則是由編譯器來決定冠场,在編譯的時候就已經(jīng)明確的知道這個函數(shù)是誰來執(zhí)行。

?????? OC的重要工作都依賴于OC獨有的一個運行期組件(Runtime Component)本砰。運行期組件本質(zhì)上就是一種與開發(fā)者寫的代碼鏈接的動態(tài)庫(dynamic library)碴裙,其功能就是把開發(fā)者的所有代碼粘合起來。

?????? 想要理解OC的內(nèi)存模型以及“引用計數(shù)”(reference counting)機制点额,首先需要明白一個前提:Objective-C語言中的指針是用來指示對象的舔株。就是對象多占內(nèi)存總是分配在堆中,而指向這個對象的指針是分配在棧中还棱。OC將堆內(nèi)存管理抽象出來了载慈,不需要用malloc和free來分配或釋放對象所占內(nèi)存。OC運行期環(huán)境把這一部分工作抽象為一套內(nèi)存管理架構(gòu)珍手,名為“引用計數(shù)”办铡。

?????? 在OC代碼中,有時會遇到不含*的變量琳要,也就是基本數(shù)據(jù)類型料扰,它們使用的是可能是“棧空間”焙蹭。比如我們設(shè)置frame,經(jīng)常用到的CGRect嫂伞,它是個c結(jié)構(gòu)體孔厉,

struct CGRect {

??? CGPoint origin拯钻;

??? CGSize size;

}撰豺;

typedef struct CGRect CGRect粪般;

?????? OC的整個系統(tǒng)框架,可以看到很多這種結(jié)構(gòu)體污桦,因為相比創(chuàng)建對象來說亩歹,節(jié)省了分配及釋放堆內(nèi)存的額外開銷。如果只需保存基本數(shù)據(jù)類型凡橱,那么通常使用這種c結(jié)構(gòu)體小作。

第二條:在類的頭文件中盡量少引入其他頭文件

?????? 關(guān)于這一點,我想所有的程序員應該多多少少都有體會稼钩,如果在類A的頭文件中引用類B的頭文件顾稀,又在類B的頭文件中引用類A的頭文件,就會造成循環(huán)引用坝撑。對于這一點OC有一個專門的引用指令#import相比#include指令静秆,雖然不會導致死循環(huán),但這卻意味著兩個類中有一個類無法被正確編譯巡李。

?????? 所以正確的做法應該是向前聲明抚笔,就是只在頭文件中聲明有另一個類,并不需要知道另一個類的全部細節(jié)侨拦。就是在類A的頭文件中使用@class B殊橙;而在實現(xiàn)文件中正確的引入類B#import “B.h”

?????? //A.h

?????? #import <Foundation/Foundation.h>

?????? @class B;

?????? @interface A : NSObject

?????? @property (nonatomic, strong) B *b;

??????? //...

??????? @end

???????? //A.m

???????? #import "A.h"

???????? #import "B.h"

???????? @implementation A

???????? //...

???????? @end

?????? 有時無法使用向前聲明,比如要聲明某個類遵循一項協(xié)議阳谍。這種情況下蛀柴,盡量把“該類遵循某協(xié)議”的這條聲明移至“class-continuation分類”中。如果不行的話矫夯,就把協(xié)議單獨放在一個頭文件中鸽疾,然后將其引入。

?????? ”class-continuation“分類就是.m文件中的@interface那一塊训貌。

第三條:多用字面量語法制肮,少用與之等價的方法

???????? 什么是字面量語法?

NSString *string = @"hello world!";???????? //字符串字面量

NSNumber *intNumber = @1;?????????????????? //字面數(shù)值

NSNumber *floatNumber = @2.5f;

NSNumber *doubleNumber = @3.14159;

NSNumber *boolNumber = @YES;

NSNumber *charNumber = @'a';

int i = 5;

folat f = 5.3f;

NSArray *array = @[@"cat",@"dog",@"pig"];?????? //字面量數(shù)組

NSString *dog = array[1];

NSDictionary *dic = @{@"firstName":@"tao",@"lastName":@"bingzhi",@"age":@25};

?????? 以上都是一些字面量的寫法递沪,那么有什么好處呢豺鼻?很直白的一點是,代碼清晰明了易讀款慨,沒有多余的語法儒飒。

?????? 同時在聲明數(shù)組和字典時,如果有一個元素是nil檩奠,這樣還會報錯桩了,而如果用數(shù)組或字典的類初始方法創(chuàng)建的話“arrayWithObjects:”會一次處理各個參數(shù)附帽,知道發(fā)現(xiàn)nil停止,不至于莫名其妙創(chuàng)建好數(shù)組之后發(fā)現(xiàn)元素少了井誉。

?????? 當然也有一定的局限性蕉扮,除了字符串之外,所創(chuàng)建出來的對象必須屬于Foundation框架才行颗圣。如果自定義了這些類的子類喳钟,則無法用字面量語法創(chuàng)建其對象。還有就是字面量創(chuàng)建出來的字符串在岂、數(shù)組和字典都是不可變的(immutable)奔则。如果想變成可變的,需要mutaleCopy以下洁段。

NSMutableArray *mutableArr = [@[@"hh",@"ss",@"tt"] mutableCopy];

第四條:多用類型常量应狱,少用#define預處理指令

?????? 寫代碼時常常需要定義常量,那么怎么定義常量才是正確且合適的祠丝,常量定義的位置又有什么講究呢疾呻?

?????? 如果我們用#define來預處理一個寬度,可能會這么寫

#define kIconWidth 30;

???????? 這雖然能解決写半,但是這樣定義出來的常量沒有類型岸蜗,代碼不易讀,可以使用下面這行代碼:

static const CGFloat kIconWidth = 30;

?????? 同時還要注意常量名稱叠蝇,常用的:若常量局限于某實現(xiàn)文件內(nèi)璃岳,則在前面加子母“k”;若常量在類之外可見悔捶,則通常以類名為前綴铃慷。

?????? 定義常量的位置也很重要,若不打算公開這個常量蜕该,則應將其定義在使用該常量的實現(xiàn)文件里犁柜。

?????? 這里需要理解一下const和static兩個關(guān)鍵字的意思,

?????? const:如果試圖修改由const修飾符所聲明的變量堂淡,那么編譯器就會報錯馋缅,不能被更新;

?????? static:就是限制了變量的可用范圍绢淀,如果是在實現(xiàn)文件中用static聲明了一個變量萤悴,那么變量的可用域就是該類所生成的目標文件,如果是在方法內(nèi)用static聲明皆的,那么可用域就是這個代碼塊覆履。

?????? 最主要的一點還是,用這種方法聲明常量帶有類型信息。

?????? 有的時候你需要公開一個常量内狗,就是無需知道這個常量名背后的意義怪嫌,只是需要用到這個常量名,例如通知名稱的公開定義柳沙。這種時候,可以將常量放在“全局符號表“中拌倍,此時應該這么聲明:

?????? //.h

?????? extern NSString *const WLLoginControllerNotification;

?????? //.m

? ? ? NSString *const WLLoginControllerNotification = @"WLLoginControllerNotification"
;

? ? ? 個人更多的還是在pch文件中赂鲤,直接寫一個通知名static const NSString * WLLoginControllerNotification = @“WLLoginControllerNotification”;

第五條:用枚舉表示狀態(tài)、選項柱恤、狀態(tài)碼

?????? 在日常開發(fā)中数初,枚舉是很好用的一個東西,可以用來表示狀態(tài)梗顺,傳遞給方法的選項以及狀態(tài)碼等值泡孩,需要主要的是,新的C++11標準修訂了枚舉的一項改動:可以指明用何種“底層數(shù)據(jù)類型”來保存枚舉類型的變量寺谤。這樣做的好處是可以向前聲明枚舉變量仑鸥,編譯器在用到枚舉的時候,就知道該給枚舉變量分配多少內(nèi)存空間了变屁。

?????? 如果把傳遞給某個方法的選項表示為枚舉類型眼俊,而多個選項又可以同時用,那么就將各選項值定義為2的冪粟关,以便通過換位或操作將其組合起來疮胖。

?????? 這里要注意一點:如果想要通過換位或操作的話,定義枚舉是就不能用NS_ENUM來定義闷板,而需要使用另一種方式定義澎灸,NS_OPTIONS,以便省去類型轉(zhuǎn)換過程遮晚。

?????? 最后一個小的tip性昭,在處理枚舉類型的switch語句中不要事先default分支,這樣的話鹏漆,加入新枚舉之后巩梢,編譯器會提示開發(fā)者:switch語句并未處理所有枚舉。

總結(jié)

?????? 今天狀態(tài)不好艺玲,寫的時候一直是很趕的情緒括蝠,不知道為什么,就沒有靜下心饭聚,很急忌警,很抱歉。可能起太早了法绵,天氣又陰沉沉的箕速,還沒吃早飯,情緒不太對朋譬。sorry sorry盐茎。

?????? 最后的最后,還是要說徙赢,換季了字柠,大家不要感冒,出門上班可以帶件外套狡赐。希望大家身體健康窑业,吃嘛嘛香。


Better Late Than Never!
努力是為了當機會來臨時不會錯失機會枕屉。

???????????????? 共勉常柄!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搀擂,隨后出現(xiàn)的幾起案子西潘,更是在濱河造成了極大的恐慌,老刑警劉巖哥倔,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秸架,死亡現(xiàn)場離奇詭異,居然都是意外死亡咆蒿,警方通過查閱死者的電腦和手機东抹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沃测,“玉大人缭黔,你說我怎么就攤上這事〉倨疲” “怎么了馏谨?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長附迷。 經(jīng)常有香客問我惧互,道長,這世上最難降的妖魔是什么喇伯? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任喊儡,我火速辦了婚禮,結(jié)果婚禮上稻据,老公的妹妹穿的比我還像新娘艾猜。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布匆赃。 她就那樣靜靜地躺著淤毛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪算柳。 梳的紋絲不亂的頭發(fā)上低淡,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機與錄音瞬项,去河邊找鬼查牌。 笑死,一個胖子當著我的面吹牛滥壕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兽泣,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼绎橘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了唠倦?” 一聲冷哼從身側(cè)響起称鳞,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稠鼻,沒想到半個月后冈止,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡候齿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年熙暴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慌盯。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡周霉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亚皂,到底是詐尸還是另有隱情俱箱,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布灭必,位于F島的核電站狞谱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏禁漓。R本人自食惡果不足惜跟衅,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望璃饱。 院中可真熱鬧与斤,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至食寡,卻和暖如春雾狈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抵皱。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工善榛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呻畸。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓移盆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親伤为。 傳聞我的和親對象是個殘疾皇子咒循,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

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