OC的起源
OC是一種消息型語言,使用的是“消息結(jié)構(gòu)”而非“函數(shù)調(diào)用”,由smalltalk演化而來。使用消息結(jié)構(gòu)的語言運行時執(zhí)行的代碼由運行環(huán)境來決定,而使用函數(shù)調(diào)用的語言由編譯器決定。
什么是引用計數(shù)
OC將堆內(nèi)存管理抽象出來了。不需要使用malloc或者free來分配或釋放對象所占的內(nèi)存。OC運行期環(huán)境把這部分工作抽象成一套內(nèi)存管理架構(gòu),名為“引用計數(shù)”。
- OC為C語言添加了面向?qū)ο筇匦?,是其超集。OC使用動態(tài)綁定的消息結(jié)構(gòu),也就是說在運行的時候才會檢查對象類型。接收一條消息后,究竟應(yīng)執(zhí)行哪種代碼,由運行期環(huán)境而非編譯器來決定。
向前聲明某類
當編譯一個A類的文件時,想要引入B類,但是不需要知道B類的全部細節(jié),只需要知道有一個類叫B類,可以使用:
@class B;
但是如果要在A類的實現(xiàn)文件中使用B,則需要使用import聲明,因為要使用它就要知道B類的所有細節(jié)。
這樣做延后了引入頭文件的時機,只有在確有需要時才引入,這樣就可以減少類的使用者所需引入的頭文件數(shù)量,減少編譯時間。
向前聲明同樣可以解決兩個類互相引用的問題。在兩個類中互相引用對方的頭文件,就會造成“循環(huán)引用”。當解析一個頭文件時,會發(fā)現(xiàn)它引用了另一個頭文件,而那個頭文件又回頭引用了第一個頭文件。使用#import而非#include雖然不會導致死循環(huán),但是會使得兩個類中有一個無法被正常編譯。
如果你寫的類繼承自某個超類,則必須引入定義那個超類的頭文件,同理如果要聲明你寫的類遵從某個協(xié)議,那么該協(xié)議必須有完整定義,且不能向前聲明。因為向前聲明只是聲明某個協(xié)議的存在,而此時編譯器卻需要知道該協(xié)議的具體定義。
- 除非確實有必要,否則不要引入頭文件。一般來說應(yīng)在某個類的頭文件中使用向前聲明來提及別的類,并在實現(xiàn)文件中引入那些類的頭文件。這樣做可以降低類之間的耦合。
有時無法使用向前聲明,比如要聲明某個類遵循一項協(xié)議。這種情況下盡量把“該類遵循某項協(xié)議”的這條聲明放在分類中。如果不行的話就把協(xié)議單獨放在一個頭文件中然后引入。
多用字面量語法
使用字面量語法可以縮減代碼長度,使其更為易讀。
NSString:
NSString *str = @“...”;
NSNumber:
NSNumber *num = @1;
NSArray:
NSArray *arr = @[@“1”, @“2”, @“3”];
NSString *two = arr[1];
NSDIctionary:
NSDictionary *dict = @{@“1”: @“one”, @“2”: @“two”, @“3”: @“three”};
NSString *two = dict[@“2”];
NSMutableDictionary和NSMutableArray:
//字面量語法修改可變數(shù)組或者字典中的元素時可這樣修改
mutableArray[1] = @“2”;
mutableDictionary[@“3”] = @“4”;
在數(shù)組中使用字面量語法時,倘若我們放入數(shù)組的元素是變量,其中一個變量為nil,那么編譯器會報出異常,方便我們及時發(fā)現(xiàn)問題。但是如果使用的不是字面量語法,比如NSArray *arr = [NSArray arrayWithObjects: obj1, obj2, obj3, nil]; 在這個數(shù)組中如果obj2為nil,那么arr的值就會只有obj1,它不會報出異常,這是因為arrayWithObjects方法處理參數(shù)時發(fā)現(xiàn)nil就停止了,這也導致我們無法及時發(fā)現(xiàn)問題。字典同理。
因此,使用字面量語法也有助于我們快速發(fā)現(xiàn)問題。
字面量語法的局限性
字面量語法有個限制就是:除了字符串以外,所創(chuàng)建的對象必須屬于Foundation框架才行。意思是自定義的這些類的子類是不能用字面量語法的。
使用字面量語法創(chuàng)建出來的字符串、數(shù)組、字典對象都是不可變的。若想要可變版本,需要:
NSMutableArray *mutableArray = [@[@1, @2, @3, @4]mutableCopy];
- 應(yīng)該使用字面量語法來創(chuàng)建字符串、數(shù)組、數(shù)值、字典。與常規(guī)方法相比。字面量語法更加簡明扼要。
應(yīng)該通過取下標操作來訪問數(shù)組下標或者字典中的鍵對應(yīng)的元素。
用字面量語法創(chuàng)建數(shù)組或字典時,若值中有nil,則會拋出異常。
多使用常量,少使用#define
定義常量應(yīng)用static const,這樣方式定義的常量包含類型信息,可以清楚的了解常量的含義。
定義的常量不應(yīng)該放在頭文件里。如果不打算公開某個常量,則應(yīng)該將其定義在實現(xiàn)文件里。
變量一定要同時用static和const聲明,如果試圖修改由const修飾符所聲明的變量,那么編譯器就會報錯。
有時候需要對外公開某個常量,比如使用通知傳值的時候要用一個對象來派發(fā)通知,然后讓其他接收通知的對象來注冊通知完成傳值。在派發(fā)通知的時候需要使用一個字符串來表明這個通知的名稱,這個名稱就可以聲明為一個外界可見的常值變量。這樣注冊者就無需知道實際字符串的值,只需要以常值變量來注冊自己想要接收的通知就行。這一類常量應(yīng)該放在“全局符號表”中,以便可以在定義該常量的編譯單元之外使用。
定義在全局符號表中:
extern NSString *const stringConst;
NSString *const stringConst = @“value”;
//在上面的代碼中,stringConst是一個指針常量,指向NSString對象。
- 不要用預(yù)處理指令定義常量。這樣定義出來的常量不含類型信息,編譯器只是會在編譯前據(jù)此執(zhí)行查找與替換操作。即使有人重新定義了常量值,編譯器也不會產(chǎn)生警告信息,這將導致應(yīng)用程序中的常量值不一致。
在實現(xiàn)文件中使用static const來定義“只在編譯單元內(nèi)可見的常量”,由于此類常量不在全局符號表中,所以無須為其命名加前綴。
在頭文件中使用extern來聲明全局變量,并在相關(guān)實現(xiàn)文件中定義其值。這種常量要出現(xiàn)在全局符號表中,所以其命名應(yīng)該加一區(qū)隔,通常用與之相關(guān)的類名做前綴。
用枚舉類型
在以一系列常量來表示錯誤狀態(tài)碼或可組合選項時,宜用枚舉為其命名。
定義枚舉的語法:
enum connectionState state = disconnected;
enum connectionState {
disconnected,
connected,
connecting,
};
typedef enum connectionState connectionState;
connectionState state = disconnected;
可以指明用何種“底層數(shù)據(jù)類型”來保存枚舉值的變量。因此這樣做就可以向前聲明枚舉變量。若不指明底層數(shù)據(jù)類型就不可以向前聲明,因為編譯器不清楚底層數(shù)據(jù)類型的大小,不知道要給它分配多少空間。
指定底層數(shù)據(jù)類型:
enum connectionState: NSInteger{...};
在向前聲明時指定底層數(shù)據(jù)類型:
enum connectionState: NSInteger;
不使用編譯器分配的序號,使用自定義指定的值:文章來源:http://www.zghlxwxcb.cn/news/detail-795795.html
enum connetcionState {
//將disconnected的值設(shè)為1,而不是編譯器指定的0,這樣接下來幾個枚舉的值都會是上一個的值+1
disconnected = 1,
connected,
connecting,
};
定義選項時可以通過枚舉組合選項,各選項之間通過“按位或操作符”來組合。文章來源地址http://www.zghlxwxcb.cn/news/detail-795795.html
- 應(yīng)該用枚舉來表示狀態(tài)機的狀態(tài)、傳遞給方法的選項以及狀態(tài)碼等值,給這些值起個易懂的名字。
如果把傳遞給某個方法的選項表示為枚舉類型,而多個選項又可以同時使用,那么就將各選項值定義為2的冪,以便通過按位或操作將其組合起來。
用NS_ENUM與NS_OPTIONS宏來定義枚舉類型,并指明其底層數(shù)據(jù)類型。這樣做可以確保枚舉是用開發(fā)者所選的底層數(shù)據(jù)類型實現(xiàn)出來的,而不會采用編譯器所選的類型。
在處理枚舉類型的switch語句中不要實現(xiàn)default分支,這樣的話,加入新枚舉之后,編譯器就會提示開發(fā)者switch語句并未處理所有枚舉。
到了這里,關(guān)于Effective Objective-C學習第一周的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!