<<Effective Objective -C 2.0>>閱讀筆記(一)

<<Effective Objective -C 2.0>>閱讀筆記只是作為騷棟的自己的心得,建議各位看官自己去看<<Effective Objective -C 2.0>>,五星推薦,推薦理由:面試儲(chǔ)備必備含友、內(nèi)存性能優(yōu)化吟逝、提高代碼質(zhì)量.非廣告~


前言


<<Effective Objective -C 2.0>>只是做閱讀的筆記,所有的筆記只是把52個(gè)相關(guān)有效方法進(jìn)行總結(jié)以及闡述騷棟的觀點(diǎn).<<Effective Objective -C 2.0>>這本書對(duì)實(shí)際開發(fā)過(guò)程中還是有著很大幫助的,尤其是項(xiàng)目的性能優(yōu)化方面有著巨大的幫助,而且如果你想當(dāng)一個(gè)iOS面試官,或者說(shuō)你要去面試iOS,那么<<Effective Objective -C 2.0>>這本書我推薦給你.我將按照讀書的每一個(gè)方法進(jìn)行記錄.看官們可以自行查看.


熟悉Objective-C(第一章標(biāo)題)


全書總共分為7個(gè)章節(jié),這一篇文章,我們主要說(shuō)一下第一章節(jié)熟悉Object-C的內(nèi)容.這一章節(jié)總共有五條建議,下面我們一一道來(lái).

  • 了解 Objective-C的起源

這個(gè)前面就說(shuō)了一堆關(guān)于OC的家族史,我們就暫時(shí)跳過(guò)了,但是我們要說(shuō)說(shuō)這個(gè)OC中獨(dú)有的"消息結(jié)構(gòu)",其實(shí)我更喜歡稱之為"消息發(fā)送機(jī)制".首先從語(yǔ)法外表上來(lái)說(shuō),相比于C語(yǔ)言的"函數(shù)調(diào)用"和其他語(yǔ)言例如java,js中通過(guò)調(diào)用某一個(gè)對(duì)象中的某一個(gè)方法都是使用"點(diǎn)語(yǔ)法".而OC中使用的是一個(gè)[]來(lái)表明某一個(gè)對(duì)象調(diào)用了某一個(gè)方法.如下示例所示.那么從本質(zhì)上來(lái)說(shuō),OC語(yǔ)言是總是在運(yùn)行的時(shí)候才去查找所需要執(zhí)行的方法.(可以查看<<Effective Objective -C 2.0>>補(bǔ)充(一):OC中的消息機(jī)制(轉(zhuǎn)載))

    NewObject *object = [[NewObject alloc]init];

    [object action];

另外這一部分還說(shuō)了一個(gè)名詞,那就是指針,指針是什么?有一本書的名字詮釋指針的定義,叫做"指針是C語(yǔ)言中一個(gè)閃亮的星星",如果C語(yǔ)言中什么最重要,那么無(wú)疑是三樣,一是指針,二是鏈表,三是結(jié)構(gòu)體.在OC中我們到處可見的就是*,作為指針,OC中沒有想C中那么要求嚴(yán)格了,但是這里有一個(gè)問(wèn)題,可能連作為資深的你都不知道,那就是 我們都知道OC中的對(duì)象是存儲(chǔ)在堆區(qū)的,那么作為指向?qū)ο蟮刂返闹羔樖谴鎯?chǔ)在什么區(qū)?難道也是堆區(qū)?,正確答案是棧區(qū).

OC作為C語(yǔ)言的超集,添加了面向?qū)ο蟮奶匦?作為一個(gè)iOS開發(fā)人員,我們使用對(duì)象那真是到了如火純青的地步了.在OC中我們也會(huì)經(jīng)常用到結(jié)構(gòu)體担平,比如CGRect,在C語(yǔ)言中結(jié)構(gòu)體的存在意義類似于OC中的對(duì)象闲勺。下面我們就比較一下兩者的區(qū)別。
首先钱磅,結(jié)構(gòu)體是存儲(chǔ)于內(nèi)存的棧區(qū)的式撼,而OC中的對(duì)象則是存儲(chǔ)在內(nèi)存的堆區(qū);再者告匠,C語(yǔ)言中的結(jié)構(gòu)體要比OC的對(duì)象中對(duì)內(nèi)存性能的影響更小戈抄。主要是原因是在于OC對(duì)象的創(chuàng)建需要額外的開銷,比如分配及釋放堆內(nèi)存等后专。


  • 在類的頭文件中盡量少引入其他頭文件

我們?cè)谝粋€(gè)類中經(jīng)常會(huì)使用到另外的一個(gè)類,那么我通常需要到導(dǎo)入頭文件,通常我們導(dǎo)入使用#import來(lái)導(dǎo)入頭文件,我們看下面一種情況,我們需要把NewObject這個(gè)類的對(duì)象作為ViewController的一個(gè)屬性,而且需要暴露出來(lái),所以把屬性寫在View Controller的頭文件中.我們可能就是用#import "NewObject.h"來(lái)導(dǎo)入到頭文件中.如下所示.

#import <UIKit/UIKit.h>
#import "NewObject.h"

@interface ViewController : UIViewController

@property(nonatomic,strong)NewObject* obj;
@end

雖然這樣是可行,但是卻不夠優(yōu)雅,在編譯的時(shí)候,我們只需要知道NewObject這個(gè)類是存在的即可,我們不需要這個(gè)類的全部細(xì)節(jié),所以這里我們使用@class導(dǎo)入對(duì)象的頭文件即可.如下所示.

#import <UIKit/UIKit.h>
@class NewObject;

@interface ViewController : UIViewController

@property(nonatomic,strong)NewObject* obj;
@end

那么這么做到底有什么好處呢?或者說(shuō),這么做到底有什么樣的優(yōu)勢(shì)呢?使用@class將引入頭文件的時(shí)機(jī)盡量延后,只在確有需要時(shí)才引入,這樣就可以減少類的使用者所需引入的頭文件數(shù)量.假設(shè)使用#import "NewObject.h"來(lái)導(dǎo)入到頭文件中,那么會(huì)一并引入NewObject的所有內(nèi)容.若此過(guò)程持續(xù)下去,則要引入許多根本用不到的內(nèi)容,會(huì)大大的增加編譯時(shí)間.另外使用@class還解決了另外的一個(gè)問(wèn)題,那就是循環(huán)引用問(wèn)題.下面我們就舉例說(shuō)明一下關(guān)于@class解決循環(huán)引用的示例.

我們假設(shè)有兩個(gè)類,分別叫FirstObject和SecondObject,在FirstObject中有一個(gè)SecondObject屬性對(duì)象,同時(shí)在SecondObject中有一個(gè)FirstObject屬性對(duì)象,同時(shí)我們都是使用#import導(dǎo)入頭文件,所以兩個(gè)類的情況就如下所示了.

#import <Foundation/Foundation.h>
#import "SecondObject.h"

@interface FirstObject : NSObject

@property(nonatomic,strong)SecondObject *sencondObject;

@end

#import <Foundation/Foundation.h>
#import "FirstObject.h"

@interface SecondObject : NSObject

@property(nonatomic,strong)FirstObject *firstObject;

@end

但是,這樣就會(huì)出現(xiàn)循環(huán)引用問(wèn)題,這是為什么呢?當(dāng)解析其中的一個(gè)頭文件的時(shí)候,編譯器會(huì)發(fā)現(xiàn)它引入另一個(gè)頭文件,而那個(gè)頭文件又回過(guò)頭來(lái)引入第一個(gè)頭文件,這樣反反復(fù)復(fù),會(huì)最終導(dǎo)致一個(gè)類無(wú)法被正確編譯.如下圖所示.

那么我們改如何解決這種循環(huán)引用問(wèn)題呢?我們只需要把兩個(gè)頭文件的任意一個(gè)導(dǎo)入換成@class方式即可,前面我們說(shuō)過(guò)@class只是說(shuō)明有這個(gè)類的存在,并不會(huì)導(dǎo)入這個(gè)類的全部信息.比如我們把FirstObject中的頭文件如下修改,然后就不會(huì)再出現(xiàn)編譯錯(cuò)誤了.

#import <Foundation/Foundation.h>
@class SecondObject;

@interface FirstObject : NSObject

@property(nonatomic,strong)SecondObject *sencondObject;

@end


  • 多用字面量語(yǔ)法,少用與之等價(jià)的方法

其中,對(duì)于字面量語(yǔ)法,這幾年學(xué)習(xí)的iOS童鞋都會(huì)使用.這種字面量語(yǔ)法從Objective-C 1.0就開始出現(xiàn)了.時(shí)代已經(jīng)相當(dāng)久遠(yuǎn)了~對(duì)于從iOS 6走過(guò)來(lái)的我們來(lái)說(shuō),我們只需要知道如何使用即可,像NSString划鸽、NSArray、NSDictionary戚哎、NSNumber這種不可變類型的對(duì)象都可以使用字面量語(yǔ)法.示例如下所示.

NSString *string = @"字面量語(yǔ)法";
NSArray *array = @[@"棟哥",@"菜哥",@"狗哥"];
NSDictionary *dictionary = @{@"key":@"value"};
NSNumber *number = @1;

使用字面量語(yǔ)法,到底有什么優(yōu)勢(shì)呢?其實(shí)主要是更為簡(jiǎn)單易讀.我們看下面兩種創(chuàng)建方式.我們發(fā)現(xiàn)使用字面量語(yǔ)法創(chuàng)建字符串更加的簡(jiǎn)答易懂.

NSString *string = @"字面量語(yǔ)法";
NSString *string = [NSString stringWithString:@"字面量語(yǔ)法"];

而且,現(xiàn)在如何使用下面的那種方式創(chuàng)建,那么會(huì)出現(xiàn)警告.如下圖所示.


  • 多用類型常量,少用#define預(yù)處理指令

在實(shí)際開發(fā)的過(guò)程中,我們經(jīng)常會(huì)使用預(yù)處理指令來(lái)定義我們常用的常量,例如我們定義一個(gè)int類型的常量,如下所示.

#define  KLength  12

但是這樣使用預(yù)處理指令到底會(huì)出現(xiàn)什么弊端呢?其實(shí),整體上來(lái)說(shuō)還是規(guī)范的問(wèn)題,首先使用預(yù)處理指令沒有表明常量的類型信息,所有不能很好的表明的描述常量的定義;而且,預(yù)處理過(guò)程會(huì)把碰到的所有的KLength替換成12,這樣的話,假設(shè)此指令聲明在某個(gè)頭文件中,那么所有引入了這個(gè)頭文件的代碼,KLength都會(huì)被替換掉.

那么,我們?cè)撊绾谓鉀Q上面闡述的兩個(gè)問(wèn)題呢,我們可以使用以下的代碼來(lái)定義KLength這個(gè)常量.我們這樣定義之后,既解決了引入頭文件無(wú)故替換問(wèn)題,而且還包含常量的類型信息.

static const int KLength = 12;


  • 用枚舉表示狀態(tài)裸诽、選項(xiàng)、狀態(tài)碼

使用枚舉來(lái)表示狀態(tài)應(yīng)該是一個(gè)很常見的使用,比如我以前寫過(guò)的SDLaunch:一個(gè)雜七雜八,卻功能完整的廣告引導(dǎo)頁(yè),SDLaunch的類型就有四種,我在使用過(guò)程中就是用了枚舉來(lái)表示不同的類型如下所示.

typedef enum {
    ADLaunchViewController,//廣告類型
    GreenhandLaunchViewController,//輪播圖新手導(dǎo)引類型
    GifBackgroundLaunchViewController,//gif圖背景類型
    RollImageLaunchViewController//滾動(dòng)圖片類型
} LaunchViewControllerType;

還有使用枚舉來(lái)表示選項(xiàng),這個(gè)是我們經(jīng)常在一些頭文件中看到的,用枚舉來(lái)表示選項(xiàng)和枚舉來(lái)表示狀態(tài)是不一樣的,一般我們用枚舉來(lái)表示狀態(tài)的時(shí)候是會(huì)選擇其中的一個(gè)枚舉值,而用枚舉來(lái)表示選項(xiàng)則是可能是多種多樣的選擇組合.換句話說(shuō)就是狀態(tài)是單選,而選項(xiàng)是多選的.

那么我們?nèi)绾问褂妹杜e來(lái)表示選項(xiàng)呢?如下所示.

//正確的選項(xiàng)枚舉示例
typedef enum {
    firstType   = 0,
    secondType  = 1<<0,
    thirdType   = 2<<0,
    fourthType  = 3<<0
}enumType;

這里我們看到了我們使用了移位符<<,首先說(shuō)明一下什么叫移位符.

位移位運(yùn)算符是將數(shù)據(jù)看成二進(jìn)制數(shù)型凳,對(duì)其進(jìn)行向左或向右移動(dòng)若干位的運(yùn)算丈冬。位移位運(yùn)算符分為左移和右移兩種,均為雙目運(yùn)算符啰脚。第一運(yùn)算對(duì)象是移位對(duì)象殷蛇,第二個(gè)運(yùn)算對(duì)象是所移的二進(jìn)制位數(shù)。

也就是說(shuō)1<<0的值為二級(jí)制的10,2<<0的值為二級(jí)制的100,那么為什么要這么做呢?我們假設(shè)不使用移位符,那么我們直接使用1,2,3,4來(lái)給枚舉賦值.如下所示.

//錯(cuò)誤的選項(xiàng)枚舉示例
typedef enum {
    firstType   = 0,
    secondType  = 1,
    thirdType   = 2,
    fourthType  = 3
}enumType;

假設(shè)我們需要是的thirdType和secondType兩個(gè)選項(xiàng),我們可以通過(guò)"按位或操作符"來(lái)組合.如下所示.但是這樣就真的沒有錯(cuò)誤了嗎?使用"按位或操作符"其實(shí)是組合兩個(gè)枚舉值的值,也就說(shuō)newType現(xiàn)在的值是3,那么跟enumType newType = fourthType;這樣是一個(gè)意義了,并不能表達(dá)選擇了多個(gè)枚舉值.

    enumType newType = secondType|thirdType;

假設(shè)我們使用了移位符<<那一套的枚舉值就不會(huì)這樣的問(wèn)題了,我們來(lái)看一下這是為什么呢?我們還是使用** enumType newType = secondType|thirdType;這時(shí)候,newType的枚舉值是多少呢?是二進(jìn)制的110,如果說(shuō)enumType newType = fourthType;**,那么枚舉值也會(huì)發(fā)生改變?yōu)?000,兩者并不是相等的,這樣我們就區(qū)分開了.示例圖像如下所示.

和枚舉經(jīng)常配合使用的經(jīng)常的switch分支語(yǔ)句,我們知道switch分支語(yǔ)句在最后都會(huì)默認(rèn)的實(shí)現(xiàn)default語(yǔ)句,這里,書中不建議我們把這個(gè)分支進(jìn)行實(shí)現(xiàn),這樣的話,如果加入新枚舉之后,那么編譯器就會(huì)提醒開發(fā)者,switch并沒有處理所有的枚舉.


結(jié)束


關(guān)于<<Effective Objective -C 2.0>>中的第一章的五個(gè)注意點(diǎn)就寫到這里,由于本文為筆記形式,所以需要更深刻的理解書中內(nèi)容,還是建議讀者去自行閱讀<<Effective Objective -C 2.0>>這本書,下面發(fā)一個(gè)PDF的書籍傳送門.大家可以去看PDF版的,如果有任何問(wèn)題歡迎聯(lián)系騷棟,我們一同探討.謝謝大家.

--> <<Effective Objective -C 2.0>>PDF版?zhèn)魉烷T??


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末橄浓,一起剝皮案震驚了整個(gè)濱河市粒梦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荸实,老刑警劉巖匀们,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異准给,居然都是意外死亡泄朴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門露氮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)祖灰,“玉大人,你說(shuō)我怎么就攤上這事畔规【址觯” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)三妈。 經(jīng)常有香客問(wèn)我畜埋,道長(zhǎng),這世上最難降的妖魔是什么畴蒲? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任悠鞍,我火速辦了婚禮,結(jié)果婚禮上模燥,老公的妹妹穿的比我還像新娘咖祭。我一直安慰自己,他們只是感情好涧窒,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布心肪。 她就那樣靜靜地躺著,像睡著了一般纠吴。 火紅的嫁衣襯著肌膚如雪硬鞍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天戴已,我揣著相機(jī)與錄音固该,去河邊找鬼。 笑死糖儡,一個(gè)胖子當(dāng)著我的面吹牛伐坏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播握联,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼桦沉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了金闽?” 一聲冷哼從身側(cè)響起纯露,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎代芜,沒想到半個(gè)月后埠褪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挤庇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年钞速,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嫡秕。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡渴语,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出昆咽,到底是詐尸還是另有隱情驾凶,我是刑警寧澤屠升,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站狭郑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏汇在。R本人自食惡果不足惜翰萨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望糕殉。 院中可真熱鬧亩鬼,春花似錦、人聲如沸阿蝶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)羡洁。三九已至玷过,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筑煮,已是汗流浹背辛蚊。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留真仲,地道東北人袋马。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像秸应,于是被迫代替她去往敵國(guó)和親虑凛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

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