Effective Objective-C 2.0 讀書筆記一

這本書中的內容都是精華,文章也很簡潔了,但是我要讓他更簡潔更易懂,由于我是一個初學者,所以就用我自己能夠理解的直白話語總結一下這52個方法,希望再看的時候理解起來不用這么麻煩,好的,馬上開始吧!

第一章 熟悉Objective-C

Objective-C(以下簡稱OC)是C語言的超集,是在C語言的基礎上添加了面向對象特性

1. 了解Objective-C的起源

首先,OC是一門面向對象語言,但是語法和其他的面向對象語言有很大差異,運用大量的中括號,這讓寫習慣其他語言的人感覺很別扭,不過,什么東西都是,習慣就好。
OC使用的是“消息結構”(messaging structure)而不是“函數調用”(function calling)是由Smalltalk演化而來,Smalltalk是消息型語言的鼻祖。好的,那么解釋一下什么是消息型語言,函數調用相信大家都理解,消息結構語言,是運行時所執行的代碼是由運行環境決定的,而不是由編譯器決定的,這就決定了OC是一門動態型語言,也就是人們說的運行時(runtime),這個怎么理解呢,就是你先聲明一下你是一個類型,但是具體是什么類型,等真正運行的時候在確定,好了,就到這,說多了我也不懂。
下面說一下OC的內存管理,OC采用引用計數機制,就是你調用一次對象,我就把引用計數加一,銷毀一次就減一,當引用計數為0的時候,系統就會把這個對象銷毀,現在在ARC環境下,計數是由編譯器幫我們管理的,所以我們很幸運,不用太糾結于這個地方。
C語言中*代表的是指針,OC中指針是用來指示對象的,所以聲明一個變量語法是:

NSString *aString = @"The string"

OC中對象都是分配在堆內存上的,所以aString這個指針指向堆內存,在堆內存中有一個NSString對象,這也就是說,如果我們再創建一個變量,讓其指向同一個內存地址:

NSString *aString = @"The string";
NSString *bString = aString;

這樣我們就創建了指向同一個內存地址的兩個指針,而不是拷貝該對象,在OC中我們有時候會看到定義一個變量不帶*,這種變量有可能使用棧內存,例如CGRect,這種變量保存的不是OC對象,而是系統框架的結構體,創建這種結構體比創建對象節省內存開銷。

2. 在頭文件中盡量少引入其他頭文件

OC編寫類的標準方式是文件名做為類名,同事生成一個.m文件和一個.h文件,一般情況下.h文件負責對外提供接口,.m文件負責內部實現,當在一個類中需要引入其他類的時候,我們就要通過#import導入其他頭文件,其實有很多時候我們在.h中引入頭文件是不需要的,我們只要用@class聲明一個類就可以了,我下面用例子說一下這么做的好處,現在有三個類

one.h
two.h
three.h

我們在two類中需要one類,我們可以這樣引入

two.h
#import "one.h"

當我們在three類中需要two類的時候我們這樣引入

three.h
#import "two.h"

那么問題來了,這樣做我們在three類中引入two類的時候間接引入了one類,而在three類中我們可能不需要one類,這樣我們在編譯的時候會增加編譯時間(注意:只是增加編譯時間,和運行時間沒有關系),雖然這樣做不會增加我們的運行時間,但是當我們間接引入過多頭文件的時候,編譯時間會大大增加,并且影響代碼的閱讀性,這個時候@class就很好用了,我們只要這樣寫:

two.h
@class one;
three.h
@class two;

這樣就可以避免在three類引入two類的時候間接引入one類了
這里的@class只是聲明一個類,而不是把類的所有細節引入,當我們要用的類的屬性、方法的時候,我們只要在.m中引入頭文件就可以了,這樣做可以提高我們的編譯效率,并且可以避免循環引用,雖然#import可以避免我們循環引用,但是在a類引用b類同時b類又引用a類的時候還是有一個類無法被正確編譯,另外這樣做還可以降低類之間的耦合。
有時候我們不得不引入頭文件,例如某個類要繼承一個父類,這個時候必須引入父類頭文件,還有我們要遵從某個協議的時候(比如代理協議),此時我們就必須要引入頭文件,來知道細節。
一般我們解決協議的引用,都是把協議放在分類里(class-continuation category)

3. 多用字面量語法

字面量語法是一種“語法糖”,OC中常用的字面量:

字面量類型 實現方式
字符串 NSString *aString = @"string"
數值 NSNumber *aNumber = @1
數組 NSArray *aArray = @[@"object1", @"object2", @"object3"]
字典 NSDictionary *aDictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"}

我們可以看到,字面量語法簡潔易懂,字面量語法的另一個好處就是當我們輸入的值為nil的時候編譯器會提示錯誤,這樣可以確保我們得到想要的字典或數組,如果我們用方法生成數組或字典可能會有不一樣的結果,例如:

id object1 = @"string1";
id object2 = nil;
id object3 = @"string3";
NSArray *aArray = [NSArray arrayWithObjects:object1, object2, object3, nil];

這樣創建出來的數組實際上只有一個對象,因為object2是nil,如果用字面量創建,會直接報錯
字面量的局限性就是創建的數組和字典都是不可變的,還有除了字符串以外,創建的對象都必須屬于Foundation框架

4. 多用類型常量,少用#define預處理指令

我們在定義一個常量的時候通常會用#define,例如:

#define kBottomMargin 25

首先說一下這么做壞處,這樣定義首先沒有描述常量類型,另外如果這樣定義在.h文件中,所有引用這個.h文件的代碼都會把kBottomMargin替換為25,我們應盡量避免這樣定義。
替代方法:

static const NSUInteger kBottomMargin = 25;

這樣定義一個常量好處是我們確定了常量類型,并且,當我們試圖修改這個常量的時候,編譯器會報錯,因為有const修飾。
這樣定義,我們解決了類型的問題,但是如果放在.h文件中定義的時候,還是無法消除引用的問題,而實際上我們有的時候要把這種常量暴露在外面,供別人使用(例如通知名稱),這時候我們可以用另外一種方法:
在.h文件中:

extern NSString *const kNotifictionName;

在.m中

NSString* const kNotifictionName = @"kNotifictionName";

這樣就圓滿解決了我們的問題,所以我們以后可以放棄用#define定義一個常量了,同時我們也要避免在.h文件中用static const來定義一個常量

5. 用枚舉表示狀態、選項、狀態嗎

枚舉的好處相信大家都知道,基本的寫法大家也都會,這里提一下大家可能忽略的地方:

  • 編譯器為枚舉值分配獨有的編號,從0開始,然而這個初始值我們可以自己設定,只要設定第一個,后面的會自動加1
  • 我們可以自行設定保存枚舉類型變量的“底層數據類型”
enum buttonState: NSInteger{/* ... */};
  • 系統為我們提供了兩種宏創建枚舉,分別是定義普通枚舉的宏NS_ENUM和創建可選多項可選類型的枚舉宏NS_OPTIONS
    例子:
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    UIViewAnimationTransitionFlipFromLeft,
    UIViewAnimationTransitionFlipFromRight,
    UIViewAnimationTransitionCurlUp,
    UIViewAnimationTransitionCurlDown,
};
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
  • switch語句中,若用枚舉來定義狀態機,最好不要有default分支,這樣做是為了確保switch語句能處理所有狀態
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容