Objective-C語言元素概述

此文概括介紹了 Objective-C 語言中的基本元素粱挡。其范圍僅限于 Objective-C 語言對 ANSI C 的擴(kuò)展赠幕,而沒有介紹 C 語言的基礎(chǔ)元素,因?yàn)榻榻B這方面的資料已經(jīng)有很多了询筏。

A.1 變量

在 Objective-C 中榕堰,變量名的詞法規(guī)則與 ANSI C 中變量名的詞法規(guī)則相同,即變量名由字母嫌套、下劃線或數(shù)字(1~9)的組合組成逆屡,但第一字符不能是數(shù)字,而且區(qū)分大小寫踱讨。

A.1.1 Objective-C 保留字

在一門編程語言中魏蔗,保留字(reserved word)是指在該語言中具有特殊意義的符號,因此它不能用作變量的名稱痹筛。在 ANSI C 相比的基礎(chǔ)上莺治,Objective-C 增加了許多保留字,如表A-1所示:

表A-1 不能用作變量名的 Objective-C 保留字

_Bool _cmd _Complex _Imaginary atomic
bycopy byref BOOL Class id
IMP inline inout instancetype out
NO nonatomic NULL SEL self
Protocol restrict retain Class id
super YES

A.1.2 變量的范圍

變量的可見性和可訪問性與其范圍有關(guān)帚稠。變量可以存在于語句塊谣旁、函數(shù)、方法滋早、對象實(shí)例(或關(guān)聯(lián)起來的對象)蔓挖、單個(gè)文件和多個(gè)文件中。ANSI C 定義了以下4種變量范圍馆衔。

  • 塊: 在語句塊中聲明的變量擁有塊范圍瘟判。在語句塊中聲明的變量只能在這個(gè)語句塊中可見和被訪問。
  • 文件:擁有文件范圍的變量只能在聲明它的文件中可見和被訪問角溃。
  • 函數(shù):在函數(shù)/方法中聲明的變量擁有函數(shù)范圍拷获。這些變量只能在相關(guān)函數(shù)/方法中可見和被訪問。
  • 函數(shù)原型:在函數(shù)/方法原型的參數(shù)列表中定義的變量擁有函數(shù)原型范圍减细。這些變量可以在相關(guān)函數(shù)/方法中可見和被訪問匆瓜。
訪問修飾符

Objective-C 增加一系列訪問修飾符指令,使用這些指令可以更精細(xì)地控制對實(shí)例變量的訪問未蝌。

Objective-C 定義了多條編譯指令驮吱,使用這些指令可以控制實(shí)例變量的范圍,即在程序中控制變量的可見性萧吠。

  • @private: 實(shí)例變量只能在聲明它的類和該類的其他實(shí)例中被訪問左冬。
  • @protected: 實(shí)例變量可以在聲明它的類和該類子類的其他實(shí)例方法中被訪問。如果沒有為實(shí)例變量指定保護(hù)級別纸型,這是默認(rèn)的變量范圍拇砰。
  • @public: 可以在任何位置訪問實(shí)例變量梅忌。
  • @package: 可在通過任何類實(shí)例和函數(shù)訪問實(shí)例變量,但在包之外除破,實(shí)例變量會被當(dāng)成私有變量牧氮。該范圍可用于庫和框架中的類。

這些指令稱為訪問修飾符瑰枫,用于修飾在實(shí)例變量聲明語句塊中聲明的實(shí)例變量踱葛。代碼清單A-1展示了類實(shí)例變量的聲明語句,這段代碼聲明了一個(gè)可在任何位置訪問的變量(int型變量counter)光坝、一個(gè)只能在聲明它的類及該類的子類中訪問的變量(float型變量temperature)尸诽,以及一個(gè)只能在聲明它的類中訪問的變量(NSString *型變量descripton)。

代碼清單A-1 使用訪問修飾符聲明實(shí)例變量

{
    @public int counter;
    @protected float temperature;
    @private NSString *description;
}

A.2 數(shù)據(jù)類型

因?yàn)?Objective-C 是 C 語言的嚴(yán)格父集教馆,所以它支持所有 ANSI C 數(shù)據(jù)類型和類型限定符逊谋。Objective-C 還定義了許多本語言專用的數(shù)據(jù)型(布爾型、類實(shí)例類型土铺、id類型胶滋、類定義類型、塊類型悲敷、枚舉類型)究恤。下面幾節(jié)詳細(xì)介紹這些內(nèi)容。

A.2.1 布爾型

布爾型是用于存儲布爾值的 Objective-C 數(shù)據(jù)類型后德,它有兩個(gè)值:真值和假值部宿。在 Objective-C 中,這兩個(gè)值被定義為 YES 和 NO瓢湃,而不是 true(1) 和 false(0)理张。為一個(gè)布爾值分配的存儲大小為1字節(jié)。Objective-C 還支持 C99 類型的 _Bool 和 bool绵患,但 BOOL 是 Objetive-C 中首選布爾數(shù)據(jù)類型雾叭。

A.2.2 類實(shí)例類型

類實(shí)例類型代表對象、類和超類(superclass)落蝙。Objective-C 運(yùn)行時(shí)環(huán)境中有多種類實(shí)例類型织狐,其中最常用的是 id 類型。

1. id類型

id 類型是所有 Objective-C 對象指針的根類型筏勒,用于存儲對任何 Objective-C 對象(不論哪種類型)的引用移迫。下面的語句聲明了一個(gè)類型?為 id、名為 myObject 的變量管行。

id myObject; // 該變量的實(shí)例化對象可以是任何類型

Objective-C 的 id 類型在程序運(yùn)行時(shí)等價(jià)于一種 C 語言結(jié)構(gòu)厨埋,該結(jié)構(gòu)被定義為指向類型定義結(jié)構(gòu) objc_object 的指針,如代碼清單A-2所示病瞳。

代碼清單A-2 id 類型的定義

typedef struct objc_object
{
    Class isa;
}  *id;

換言之揽咕,id 僅是一個(gè)指向含有 objc_object 標(biāo)識符的 C 語言結(jié)構(gòu)的指針悲酷。

2. instancetype 關(guān)鍵字

instancetype是一個(gè)上下文關(guān)鍵字套菜,可用作方法結(jié)果的數(shù)據(jù)類型亲善,它表明方法返回了相關(guān)結(jié)果類型。方法返回相關(guān)結(jié)果類型是指方法返回接收對象所屬類的實(shí)例逗柴。通過相關(guān)結(jié)果類型可以推斷出下列方法類型:

  • 以 alloc 或 new 開頭的類方法蛹头;
  • 以 autorelease、init戏溺、retain 或 self 開頭的實(shí)例方法渣蜗。

下面語句使用關(guān)鍵字 new 創(chuàng)建了一個(gè) OrderItem 對象。

OrderItem *item = [OrderItem new];

盡管 NSObject 類的 new 方法將 id 設(shè)置為返回類型旷祸,但編譯器會根據(jù)名為 item 的接收對象所屬的類,推斷正確的結(jié)果類型(本例中為 OrderItem *)。

instancetype 關(guān)鍵字可用于明確指明腕巡,方法返回的是相關(guān)結(jié)果類型顶瞒。代碼清單A-3展示了 OrderItem 類的一個(gè)例子,該類的接口定義了一個(gè)返回相關(guān)結(jié)果類型的方法闰围。

代碼清單A-3 使用 instancetype 關(guān)鍵字返回相關(guān)結(jié)果類型的值

@interface OrderItem : NSObject
+ (instancetype)orderItemWithDescription:(NSString *)description 
                                   price:(float)cost;
@end

A.2.3 類定義類型

類定義類型定義了 Objective-C 運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)赃绊。它們包括 SEL、IMP羡榴、Class碧查、objc_object類型。

1. SEL 類型

SEL 類型代表方法選擇器校仑,是一種在 Objective-C 運(yùn)行時(shí)環(huán)境中代表方法名稱的數(shù)據(jù)類型忠售。使用編譯器指令 @selector,可以為名為 helloworld 的方法選擇器創(chuàng)建 SEL 類型的變量:

SEL myHelloMethod = @selector(helloWorld);

該選擇器可用于調(diào)用對象中的 helloWorld 方法迄沫。

2. IMP 類型

IMP 類型代表一種方法指針稻扬,這種指針指向?qū)崿F(xiàn)方法的函數(shù)的內(nèi)存起始地址。下面是定義 IMP 的類型的語法:

typedeff id (*IMP)(id, SEL, ...);

如這個(gè)類型定義所示邢滑,被 IMP 類型指向的函數(shù)接收一個(gè) id 類型腐螟、一個(gè)方法選擇器(SEL)和可變參數(shù)(由可變參數(shù)符號...代表)作為參數(shù),并返回 id 類型的結(jié)果困后。

3. Class 類型

Class 類型代表 Objective-C 類實(shí)例(即對象)乐纸,由各種數(shù)據(jù)元素構(gòu)成。下面是定義 Class 數(shù)據(jù)類型的語法:

typedef struct objc_class *Class;

如這個(gè)類型定義所示摇予,Class 數(shù)據(jù)類型是一種指針汽绢,這種指針指向帶 objc_class 標(biāo)識符的不透明類型。objc_class 結(jié)構(gòu)的成員只能由專門定義的函數(shù)(尤其是使用 Objective-C 運(yùn)行時(shí)庫函數(shù))訪問侧戴。

4. objc_object 類型

Objective-C 對象擁有相應(yīng)的運(yùn)行時(shí)數(shù)據(jù)類型宁昭。當(dāng)編譯器解析 Objective-C 對象的代碼時(shí)跌宛,會生成創(chuàng)建運(yùn)行時(shí)對象類型的代碼,即 objc_object 類型积仗。如代碼清單A-4所示疆拘, 這種數(shù)據(jù)類型是一種帶 objc_object標(biāo)識符的 C 語言結(jié)構(gòu)。

代碼清單A-4 objc_object

struct objc_object
{
    Class isa;
    /* ...含有實(shí)例變量值的可變長度數(shù)據(jù)... */
}

objc_object類型含有一個(gè)變量寂曹,該變量的類型為 Class哎迄、名稱為 isa;換言之隆圆,它是一個(gè)指向 objc_class 類型變量的指針漱挚。

A.2.4 塊類型

塊提供了創(chuàng)建一組語句(即語句塊)并將其賦予變量(以便在將來調(diào)用)的方式。塊類似于 C 語言的標(biāo)準(zhǔn)函數(shù)渺氧,但塊除了是可執(zhí)行代碼外旨涝,還含有與堆內(nèi)存或棧內(nèi)存綁定的變量。塊是一種 Objective-C 對象(類型為塊)侣背,而且與所有 Objective-C 對象一樣白华,它也是通過指針被訪問的。像處理 Objective-C 對象一樣秃踩,使用 id 類型可以引用塊對象衬鱼。下面的語句聲明了一個(gè)名為 incrementSum 的塊類型變量,該變量擁有一個(gè)類型為 int 的參數(shù)并且不會返回任何值憔杨。

void (^incrementSum)(int);

可以使用存儲修飾符 __block 創(chuàng)建塊變量鸟赫。它可以應(yīng)用于同一詞法范圍內(nèi)、塊常量外部的變量消别,并使用該變量能夠在這個(gè)塊常量中修改抛蚤。該存儲修飾符無法與本地存儲修飾符 auto、register 和 static 應(yīng)用于同一個(gè)變量寻狂。代碼清單A-5給出了 __block 存儲修飾符的用法岁经。

代碼清單A-5 __block 存儲修飾符的用法

__block int totalSum = 0;
void (^incrementSum)(int) = ^(int amount) {
    totalSum += amount;
    NSLog(@"Current total = %d", totalSum);
};
incrementSum(5);

執(zhí)行代碼清單A-5所示代碼,會輸出如下結(jié)果蛇券;

Current total = 5

因此缀壤,塊變量 totalSum 被初始化為0,然后在調(diào)用該塊常量時(shí)被修改纠亚。

A.2.5 枚舉類型

Objective-C 支持標(biāo)準(zhǔn)的 C 語言枚舉類型塘慕,并且為指定枚舉的類型提供了支持。枚舉類型由使用關(guān)鍵 enum 定義的一系列已命名值(也稱為“枚舉器”)構(gòu)成蒂胞。被聲明為枚舉型的變量可以被賦予任何枚舉器值图呢。代碼清單A-6定義了含有一組值的枚舉型變量,該變量的名稱為 color,含有 Red蛤织、Green 和 Blue 值赴叹。

代碼清單A-6 枚舉型定義示例

enum
{
    Red,
    Green,
    Blue,
} color;

枚舉器的默認(rèn)類型為 int。Objective-C 支持顯示地設(shè)置枚舉的類型指蚜,這也稱為“含有固定基礎(chǔ)類型的枚舉類型”乞巧。枚舉支持的基礎(chǔ)類型是帶符號或不帶符號的整型(char、short姚炕、int摊欠、long)丢烘。類型應(yīng)該在 enum 關(guān)鍵字之后指定柱宦,而且前面要加冒號(:)。代碼清單A-7所示的代碼定義了一個(gè)枚舉型變量播瞳,它的名稱為 color掸刊,含有一個(gè)組類型為 unsigned char 的值:Red、Greed赢乓、Blue忧侧。

代碼清單A-7 含有固定基礎(chǔ)類型的枚舉類型

enum : unsigned char
{
    Red,
    Green,
    Blue,
} color;

通常,可使用類型定義聲明枚舉類型牌芋。代碼清單A-8所示的代碼使用類型定義聲明了一個(gè)枚舉型變量蚓炬,該變量的名稱為 color,含有一組類型為 unsigned char 的值:Red躺屁、Greed肯夏、Blue。

代碼清單A-8 含有固定基礎(chǔ)類型的枚舉類型定義

typedef enum : unsigned char
{
    Red,
    Green,
    Blue,
} ColorType;
ColorType color;

在 Objective-C 中犀暑,定義枚舉型值的首選方式是用 NS_ENUM 宏驯击。該宏提供一種約定機(jī)制來聲明枚舉值的基礎(chǔ)類型,并使用一條語句定義新的枚舉類型耐亏。代碼清單A-9使用 NS_ENUM 宏定義了代碼清單A-8中定義的枚舉類型徊都。

代碼清單A-9 使用 NS_ENUM 宏定義枚舉類型

typedef NS_ENUM(unsigned char, ColorType)
{
    Red,
    Green,
    Blue,
};

如代碼清單A-9所示,這個(gè)宏的第一個(gè)參數(shù)是基礎(chǔ)類型广辰,而它的第二個(gè)參數(shù)是新枚舉類型的名稱暇矫。像普通塊語句一樣,這些值會存儲在語句塊中择吊。

A.3 操作符

Objective-C 支持 ANSI C 定義的操作符李根,尤其是下面這些操作符:

  • 賦值操作符
  • 算術(shù)操作符
  • 復(fù)合賦值操作符
  • 增量和減量操作符
  • 邏輯比較操作符
  • 邏輯判斷操作符
  • 逐位運(yùn)算操作符
  • 復(fù)合逐位運(yùn)算操作符
  • 三元運(yùn)算操作符
  • 類型轉(zhuǎn)換操作符
  • sizeof操作符
  • 地址操作符(&)
  • 間接操作符(*)
  • 逗號操作符

要詳細(xì)了解這些算術(shù)轉(zhuǎn)換法則以及這些操作符的優(yōu)先等級和關(guān)系,請參閱 ANSI C 的規(guī)定干发。

脫字操作符(^)用于處理塊對象朱巨,特別是聲明塊對象類型和定義塊常量。

A.4 語句

Objective-C 支持 ANSI C 定義的條件枉长、循環(huán)和跳轉(zhuǎn)語句冀续,尤其是下面這些語句:

  • 條件語句(if琼讽、if else、if else if洪唐、switch)
  • 循環(huán)語句(for钻蹬、while、do while)
  • 跳轉(zhuǎn)語句(return凭需、goto问欠、break、continue)

A.5 類元素

Objective-C 中的類由多個(gè)結(jié)構(gòu)化元素構(gòu)成粒蜈,這些元素通常分為幾個(gè)部分顺献。本節(jié)概括介紹這些基本類元素。

A.5.1 實(shí)例變量

實(shí)例變量是為類聲明的變量枯怖,用于在類實(shí)例的生命周期中保存實(shí)例的值注整。實(shí)例變量會在對象被初次創(chuàng)建時(shí)被分配內(nèi)存,并在對象被釋放時(shí)被釋放內(nèi)存度硝。實(shí)例變量擁有與對象對應(yīng)的默認(rèn)作用范圍和命名空間肿轨。可以在類接口蕊程、類實(shí)現(xiàn)文件或類擴(kuò)展的實(shí)例變量聲明語句塊中聲明實(shí)例變量椒袍。實(shí)例變量的聲明語句塊必須緊跟相應(yīng)的接口、實(shí)現(xiàn)文件和類擴(kuò)展聲明語句藻茂。代碼清單A-10展示了聲明 Hello 類實(shí)例變量的例子驹暑。

代碼清單A-10 Hello類實(shí)現(xiàn)文件中聲明實(shí)例變量的語句塊

@implementation Hello
{
    // 在此處聲明實(shí)例變量
    ...
}
...
@end

建議在類的實(shí)現(xiàn)文件(而不是公共的類接口)中聲明實(shí)例變量。通常應(yīng)在類實(shí)現(xiàn)文件專用的變量擴(kuò)展中聲明實(shí)例變量捌治。

實(shí)例變量的所有權(quán)限定符

Objective-C 所有權(quán)限定符是一種只能應(yīng)用于可保留對象指針的類型限定符岗钩。要設(shè)置變量的所有權(quán)規(guī)則,應(yīng)在變量聲明中將所有權(quán)限定符放置在對象指針類型之前肖油。表A-2列出了4個(gè)所有權(quán)限定符兼吓。

限定符 描述
__autoreleasing 當(dāng)變量被賦予新值時(shí),新值會被保留和自動釋放森枪,而舊值會被發(fā)送釋放消息
__weak 變量使用簡單賦值操作(即不復(fù)制或保留輸入值)视搏。如果對象被釋放了,相應(yīng)的變量值會被設(shè)置為nil
__unsafe_unretained 變量使用簡單賦值操作(即不復(fù)制或保留輸入值)
__strong 當(dāng)變量被賦予新值時(shí)县袱,新值會被保留浑娜,而舊值會被發(fā)送釋放消息

默認(rèn)的所有權(quán)限定符為__strong(在沒有明確設(shè)置限定符的情況下)。下面語句聲明了一個(gè)名為hello的變量(類型為 Hello *)式散,其所有權(quán)限定符為 __weak筋遭。

__weak Hello *hello;

A.5.2 屬性

在 Objective-C 中,屬性通過訪問方法(即獲取方法和設(shè)置方法),為訪問對象的共享狀態(tài)提供了一種便利機(jī)制漓滔。屬性與實(shí)例變量的區(qū)別在于编饺,屬性不直接訪問對象的內(nèi)部狀態(tài)。在處理 Objective-C 屬性時(shí)响驴,編譯器可以根據(jù)你提供的規(guī)格自動生成訪問方法透且。

可以使用 @property 關(guān)鍵字聲明屬性,后跟一系列可選特性(封閉在圓括號內(nèi))豁鲤、屬性類型和屬性名稱秽誊。

 @property (特性) 類型 屬性名稱;

屬性聲明特性用于設(shè)置存儲語義和其他屬性行為。表A-3列出了可用的屬性特性琳骡。

表A-3 屬性的特性

屬性 描述 注釋
readwrite 必選 訪問限定符锅论。默認(rèn)設(shè)置
readonly 必選 訪問限定符。無法同時(shí)選擇 readwrite 和 readonly
assign 使設(shè)置方法使用簡單賦值操作(即不復(fù)制或保留輸入值) 所有權(quán)限定符日熬。在手動內(nèi)存管理方式(MRR)中使用棍厌。MRR 中的默認(rèn)值
weak 使設(shè)置方法使用簡單賦值操作。如果屬性實(shí)例被釋放了竖席,那么支持屬性的實(shí)例變量會被設(shè)置為 nil 所有權(quán)限定符。在 ARC 內(nèi)存管理方式中使用
unsafe_unretained 使設(shè)置方法使用簡單賦值操作 所有權(quán)限定符敬肚。在 ARC 內(nèi)存管理方式中使用
copy 在使用設(shè)置方法賦值時(shí)毕荐,調(diào)用復(fù)制方法并向舊值發(fā)送釋放信息 所有權(quán)限定符
retain 在設(shè)置方法中,舊值會被發(fā)送釋放消息艳馒,而屬性會使用保留賦值操作 所有權(quán)限定符憎亚。與強(qiáng)引用特性類似(在手動內(nèi)存管理方式中使用)
strong 在設(shè)置方法中,舊值會被釋放消息弄慰,而屬性會使用保留賦值操作 在 ARC 內(nèi)存管理方式中使用的所有權(quán)限定符第美。ARC 中的默認(rèn)設(shè)置
getter=getterName 使用“獲取方法的名稱”指定獲取方法的名稱 ----
setter=setterName 使用“設(shè)置方法的名稱”指定設(shè)置方法的名稱 ----
nonatomic 將屬性的訪問方法設(shè)置為非自動生成(默認(rèn)設(shè)置)。nonatomic 屬性擁有更好的性能陆爽,但無法保證當(dāng)多個(gè)線程訪問屬性時(shí)什往,能夠通過屬性訪問方法返回具有線程安全性的值 ----

屬性定義是在類的實(shí)現(xiàn)文件中實(shí)現(xiàn)的。在大多數(shù)情況下慌闭,屬性是由實(shí)例變量支持的别威,因此屬性定義包括定義屬性的獲取方法和設(shè)置方法、聲明實(shí)例變量以及在獲取/設(shè)置方法中使用這些實(shí)例變量驴剔。 Objective-C 提供了3種定義屬性的方式:顯示定義省古、通過關(guān)鍵字補(bǔ)全和自動補(bǔ)全。

A.5.3 方法

Objective-C 既支持實(shí)例方法丧失,也支持類方法豺妓。實(shí)例方法是指在類實(shí)例(對象)中調(diào)用的方法,因此,實(shí)例方法可以直接訪問對象的實(shí)例變量琳拭。類方法是指在類中調(diào)用的方法载佳。可以在類的接口臀栈、協(xié)議和類別(category)中聲明方法蔫慧。因此,應(yīng)在相應(yīng)的類/類別的實(shí)現(xiàn)文件中定義已聲明的類权薯。

方法的聲明設(shè)置了方法的類型姑躲、返回值的類型、方法的名稱盟蚣、方法的參數(shù)和相應(yīng)的參數(shù)類型黍析。方法的類型標(biāo)識符指明了該方法是類方法還是實(shí)例方法。類方法的聲明中含有一個(gè)加號(+)屎开,它表明方法的作用范圍為類阐枣,這意味著方法作用類一級,無法訪問類中的實(shí)例變量(除非將它們作為參數(shù)傳遞給方法)奄抽。實(shí)例方法的聲明中含有一個(gè)減號(-)蔼两,它表明這些方法的作用范圍為對象。這意味著這些方法作用于對象一級逞度,而且可以直接訪問對象及其父對象中的實(shí)例變量(在遵守這些實(shí)例變量訪問控制規(guī)定的情況下)额划。

方法的名稱中含有參數(shù)和冒號。每個(gè)參數(shù)的類型都是在圓括號中設(shè)置的档泽,后跟方法原型參數(shù)俊戳。參數(shù)的名稱和類型由冒號分隔,如下例所示:

-(void)incrementSum:(int)value;

該方法的名稱為 incrementSum:馆匿,它擁有一個(gè) int 型的參數(shù) value抑胎。如果方法含有多個(gè)參數(shù),就需要多個(gè)名稱-參數(shù)對渐北,如下例所示:

-(int)addAddend1:(int)a1 addend2:(int)a2;

該方法的名稱為 addAddend1:addend2:阿逃,它擁有兩個(gè) int 型的參數(shù) a1 和 a2。

返回類型用于設(shè)置方法返回變量的類型(如果存在返回變量)腔稀。返回類型是在圓括號中設(shè)置的盆昙,后跟方法的類型。如果方法沒有返回值焊虏,那么就應(yīng)將返回類型聲明為 void淡喜。

下面的語句聲明了一個(gè)類方法,它的名稱為 hydrogenWithProthons:neutrons:诵闭,擁有兩個(gè) unsigned int 型的參數(shù) nProtons 和 nNeutrons炼团。

+ (void)hydrogenWithProthons:(unsigned)nProtons neutrons:(unsigned)nNeutrons;

A.5.4 接口

類接口設(shè)置了類的狀態(tài)和行為澎嚣,封裝了實(shí)例變量、屬性和方法瘟芝。類接口的聲明以 @interface 指令和類名稱開頭易桃,以 @end 指令結(jié)束。代碼清單A-11展示了聲明類接口的正式語法锌俱。

代碼清單A-11 類接口的聲明語法

@interface 類的名稱 : 父類的名稱
{
    // 實(shí)例變量的聲明
    ...
}
    // 屬性和方法的聲明
    ...
@end

父類創(chuàng)建了通用接口和實(shí)現(xiàn)代碼晤郑,子類可以繼承、修改和補(bǔ)充這些元素贸宏。Objective-C 中的絕大多數(shù)類都是 NSObject 類的子類造寝,NSObject 類是大多數(shù) Foundation 框架的根類(基類),它提供了 Objective-C 運(yùn)行時(shí)環(huán)境的基礎(chǔ)接口吭练。

提前聲明

使用 @class 指令可以在獲取類的完整規(guī)格前诫龙,在類接口中聲明類。這樣做可以在無須導(dǎo)入相應(yīng)頭文件的情況下鲫咽,告訴編譯器類的存在签赃,從而使編譯器能夠執(zhí)行靜態(tài)類型檢查。提前聲明可用于解決文件之間的循環(huán)依賴問題分尸。

A.5.5 實(shí)現(xiàn)代碼

類的實(shí)現(xiàn)文件通過實(shí)現(xiàn)類的屬性和方法定義了類的行為锦聊。類實(shí)現(xiàn)文件以 @implementation 指令和類的名稱開頭,以 @end 指令結(jié)束寓落。代碼清單A-12展示了聲明類實(shí)現(xiàn)文件的正式語法括丁。

代碼清單A-12 類實(shí)現(xiàn)文件的語法

@implementation 類的名稱
{
    // 實(shí)例變量的聲明
    ...
}
    // 屬性和方法的定義
    ...
@end

在類實(shí)現(xiàn)文件中定義的方法必須直接與相應(yīng)的類接口對應(yīng),例如伶选,代碼清單A-13所示的代碼創(chuàng)建了 Greeting 類的接口和相應(yīng)的實(shí)現(xiàn)代碼。

代碼清單A-13 Greeting類接口和實(shí)現(xiàn)代碼

#import <Foundation/Foundation.h>

@interface Greeting : NSObject
@property (readwrite) NSString *salutation;
-(void)hello:(NSString *)user;
@end

#import "Greeting.h"
@implementation Greeting
-(void)hello:(NSString *)user
{
    NSLog(@"%@, %@", self.salutation, user);
}
@end

A.5.6 協(xié)議

協(xié)議規(guī)定了類可以實(shí)現(xiàn)的方法和屬性尖昏。協(xié)議的聲明以 @protocol 指令開頭仰税,后跟協(xié)議的名稱,以 @end 指令結(jié)束抽诉。協(xié)議中含有必選和可選方法陨簇。協(xié)議的實(shí)現(xiàn)代碼無須實(shí)現(xiàn)可選方法。@required 指令和 @optional 指令(后跟一個(gè)或多個(gè)方法名稱)用于設(shè)置必選和可選方法迹淌。如果沒有明確設(shè)置這兩個(gè)關(guān)鍵字中的任何一個(gè)河绽,那么默認(rèn)為使用 @required 指令。代碼清單A-14展示了聲明協(xié)議的語法唉窃。

代碼清單A-14 聲明協(xié)議的語法

@protocol 協(xié)議的名稱
// 屬性的聲明
@required
// 方法的聲明
@optional
// 方法的聲明
@end

通過在尖括號中設(shè)置其他協(xié)議耙饰,可以組合使用協(xié)議,這稱為遵守其他協(xié)議纹份。逗號用于分隔多個(gè)協(xié)議苟跪,如代碼清單A-15所示廷痘。

代碼清單A-15 組合使用多個(gè)協(xié)議

@protocol 協(xié)議的名稱<協(xié)議的名稱>
// 方法的聲明
@end

通過類似的語法可以使用接口遵守多個(gè)協(xié)議,如代碼清單A-16所示件已。

代碼清單A-16 使接口遵守協(xié)議的語法

@interface 類的名稱 : 父類的名稱<協(xié)議的名稱>
// 方法的聲明
@end

通常笋额,類的接口和實(shí)現(xiàn)代碼存儲在不同的文件中,存儲接口的頭文件擁有 .h 后綴篷扩,而實(shí)現(xiàn)文件擁有 .m 后綴兄猩。

A.5.7 類別

通過類別(category)可在不進(jìn)行子類化的情況下,為已經(jīng)存在的類添加功能鉴未。類別中的方法會變成類的組成部分(在程序范圍之內(nèi))枢冤,并且會被該類的所有子類繼承。

類別接口聲明以 @interface 關(guān)鍵字開頭歼狼,后跟已經(jīng)存在的類名稱掏导、由圓括號封裝的類別名稱以及類別遵守的協(xié)議(如果存在),以 @end 關(guān)鍵字結(jié)束羽峰。應(yīng)在這些語句之間添加方法的聲明趟咆。代碼清單A-17展示了聲明類別的語法。

代碼清單A-17 聲明類別的語法

@interface 類的名稱(類別的名稱)
// 方法的聲明
@end

與類的實(shí)現(xiàn)文件相似梅屉,類別在其實(shí)現(xiàn)中定義方法值纱。代碼清單A-18展示了類別實(shí)現(xiàn)的語法:

代碼清單A-18 類別實(shí)現(xiàn)的語法

@implementation 類的名稱(類別的名稱)
// 方法的定義
@end

A.5.8 類擴(kuò)展

可以將類擴(kuò)展為匿名類別。在類擴(kuò)展中聲明的方法必須在相應(yīng)類的實(shí)現(xiàn)文件中實(shí)現(xiàn)坯汤。與類別相反虐唠,類擴(kuò)展可以聲明實(shí)例變量和屬性。代碼清單A-19展示了類擴(kuò)展的語法:

代碼清單A-19 聲明類擴(kuò)展的語法

@interface 類的名稱()
{
    // 實(shí)例變量的聲明
}
// 屬性的聲明
// 方法的聲明
@end

通常惰聂,可以將類擴(kuò)展放在類的實(shí)現(xiàn)文件中疆偿,使用它們組織和聲明額外的、必要的私有方法(如不屬于已聲明的公用 API 的方法)搓幌,以單獨(dú)在某個(gè)類中使用杆故。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市溉愁,隨后出現(xiàn)的幾起案子处铛,更是在濱河造成了極大的恐慌,老刑警劉巖拐揭,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撤蟆,死亡現(xiàn)場離奇詭異,居然都是意外死亡堂污,警方通過查閱死者的電腦和手機(jī)家肯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敷鸦,“玉大人息楔,你說我怎么就攤上這事寝贡。” “怎么了值依?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵圃泡,是天一觀的道長。 經(jīng)常有香客問我愿险,道長颇蜡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任辆亏,我火速辦了婚禮风秤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扮叨。我一直安慰自己缤弦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布彻磁。 她就那樣靜靜地躺著碍沐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衷蜓。 梳的紋絲不亂的頭發(fā)上累提,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音磁浇,去河邊找鬼斋陪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛置吓,可吹牛的內(nèi)容都是我干的无虚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼衍锚,長吁一口氣:“原來是場噩夢啊……” “哼骑科!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起构拳,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梁棠,沒想到半個(gè)月后置森,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡符糊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年凫海,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片男娄。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡行贪,死狀恐怖漾稀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情建瘫,我是刑警寧澤崭捍,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站啰脚,受9級特大地震影響殷蛇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜橄浓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一粒梦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荸实,春花似錦匀们、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至圆存,卻和暖如春叼旋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沦辙。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工夫植, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人油讯。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓详民,卻偏偏與公主長得像,于是被迫代替她去往敵國和親陌兑。 傳聞我的和親對象是個(gè)殘疾皇子沈跨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

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