精通Objective C 物件和訊息傳遞

2021-07-14 05:59:01 字數 4529 閱讀 1705

訊息傳遞

附錄前一章節建立的atom類

nsobject類中用於建立類例項(即物件)的方法

+(id) alloc
通過alloc方法,可以建立物件,下面以建立乙個atom物件為例

//建立乙個屬於atom類的物件,並為它分配乙個資料型別為id的變數

id atom = [atom alloc];

//與上面語句等價,顯示定義變數的型別,失去靈活性,但可以獲得靜態型別檢查

atom *atom = [atom alloc];

alloc方法為物件分配了記憶體,並將它的例項變數設定為0,但是alloc方法既沒有將該物件的例項變數初始化為適當的值,也沒有為這個物件準備其他必須的物件和資源。因此自定義的類還應該實現完成初始化的過程的方法。

nsobject類中用於初始化物件的方法:

-(id) init
下面以atom類的init方法為例:

-(id) init

return

self;

}

編譯器自動補全屬性時,建立的是乙個作用範圍為@private的支援例項變數,無法被該類的子類訪問。可以重構該類,將這個變數的作用範圍設定為@protected。

@inte***ce

atom : nsobject

//重構atom類,宣告作用範圍為@protected的支援例項變數

//之前宣告的屬性和方法

@property(readonly) nsuinteger protons;

@property(readonly) nsuinteger neutrons;

@property(readonly) nsuinteger electrons;

@property(readonly) nsstring *chemicalelement;

@property(readonly) nsstring *atomicsymbol;

-(nsuinteger) massnumber;

@end

建立乙個atom類的子類hydrogen,並使用新的可以接受引數的初始化方法。

hydrogen.h

#import "atom.h"

@inte***ce

hydrogen : atom

//宣告初始化方法

-(id) initwithneutrons:(nsuinteger)neutrons;

@end

hydrogen.m

#import "hydrogen.h"

@implementation

hydrogen

//實現初始化方法

-(id) initwithneutrons:(nsuinteger)neutrons

return

self;

}@end

工廠方法是指用於建立和初始化類的便捷方法

在hydrogen.h中宣告

+(id) hydrogenwithneutrons:(nsuinteger)neutrons;
在hydrogen.m實現

+(id) hydrogenwithneutrons:(nsuinteger)neutrons
之後我們就可以用兩種不同的方法來完成物件的初始化了

//普通方法

hydrogen *atom1 = [[hydrogen alloc] initwithneutrons:1];

//工廠方法

hydrogen *atom2 = [hydrogen hydrogenwithneutrons:2];

訊息傳遞是oop中的用於呼叫物件中方法的機制。接收訊息的物件(接收器)會在執行時決定呼叫其實例的哪個方法。例項方法可以訪問物件的例項變數和例項方法。

向物件傳送訊息的格式:

[接收器 訊息名稱1:引數1 訊息名稱2:引數2

...]

同時objective-c還為類方法提供了語言級的支援:

[類名 訊息名稱1:引數1 訊息名稱2:引數2

...]

之前的[hydrogen hydrogenwithneutrons:2]就是向hydrogen類傳送訊息。

在執行時,接收器都會通過解釋訊息,確定需要呼叫哪個方法。objective-c提供了訊息**機制,當物件收到與其方法集不匹配的訊息時,通過訊息**機制可以使物件能夠在收到無法識別的資訊時執行各種邏輯,如將訊息傳送給能夠作出回應的其他接收器或是既不處理也不使程式丟擲執行時錯誤,默默吞下訊息。

objective-c為nsobject類的子類提供了兩類訊息**選項。

快速**:

//重寫nsobject類的該方法,將該方法**給其他物件,就像是將物件的實現**與**物件合併到了一起,類似於類實現的多重繼承行為

-(id) forwardingtargetforselector:(sel)aselector

標準(完整)**:

//重寫nsobject類的該方法,可以讓物件使用訊息中的全部內容(目標,方法名和引數)

-(void) forwardinvocation:(nsinvocation *)aninvocation

下面來為hydrogen類新增快速**機制。

首先需要建立乙個輔助類hydrogenhelper,該類負責處理乙個名為factoid的hydrogen類無法處理的方法。

hydrogenhelper.h

#import 

@inte***ce

hydrogenhelper : nsobject

-(nsstring *) factoid;

@end

hydrogenhelper.m

#import "hydrogenhelper.h"

@implementation

hydrogenhelper

-(nsstring *) factoid

@end

再更新hydrogen類的**

@implementation

hydrogen

//新增例項變數hydrogenhelper

-(id) initwithneutrons:(nsuinteger)neutrons

return

self;

}+(id) hydrogenwithneutrons:(nsuinteger)neutrons

//重寫nsobject類的forwardingtargetforselector:(sel)aselector方法

-(id) forwardingtargetforselector:(sel)aselector

return

nil;

}@end

為了使hydrogen類能夠接收factoid方法,還需再新增乙個分類,在其中宣告factoid方法(不需要實現)

atom+helper.h(由於不需要實現方法可以把自動建立出來的atom+helper.m刪掉)

#import "atom.h"

//也可以將atom改為hydrogen

@inte***ce

atom (helper)

//宣告factoid方法

-(nsstring *) factoid;

@end

最後就可以通過訊息**功能,向hydrogen物件傳送factoid方法了

hydrogen *atom =[hydrogen hydrogenwithneutrons:2];

[atom factoid];

atom.h

#import 

@inte***ce

atom : nsobject

@property(readonly) nsuinteger protons;

@property(readonly) nsuinteger neutrons;

@property(readonly) nsuinteger electrons;

@property(readonly) nsstring *chemicalelement;

-(nsuinteger) massnumber;

@end

atom.m

#import "atom.h"

@implementation

atom

-(id) init

return

self;

}-(nsuinteger) massnumber

@end

Objective C之類和物件

面向過程程式設計 procedure oriented programming,pop 以事件為中心,關心完成該事件的詳細步驟,一步一步如何實現.物件導向程式設計 object oriented programming,oop 以事物為中心,也就是引數事件的參與者,設計事物的功能,而完成事件只是事物...

Objective C從入門到精通

字元常量 按位運算子 未完待續 objective c是通用語言,它是在c語言程式語言之上開發的,它增加了small talk程式語言的功能,使objective c成為物件導向的語言。它主要用於開發ios和mac os x作業系統及其應用程式。最初,objective c是由next為其nexts...

Objective C語法之類和物件

下圖中是一段的類宣告的語法展示,宣告了乙個叫做 myclass 的類,它繼承於根類 nsobject。根類可以被所有的其他類直接或間接繼承。下圖是乙個方法的語法展示,方法的宣告由以下幾個部分構成 方法型別識別符號,返回型別,乙個或多個方法簽名關鍵字,以及引數型別和名稱。類的實體變數的訪問許可權 對應...