Objective-C之成魔之路【9-類構造方法和成員變數範圍、以及變數】,objective-c9-

來源:互聯網
上載者:User

Objective-C之成魔之路【9-類構造方法和成員變數範圍、以及變數】,objective-c9-

郝萌主傾心貢獻,尊重作者的勞動成果,請勿轉載。

如果文章對您有所協助,歡迎給作者捐贈,支援郝萌主,捐贈數額隨意,重在心意^_^ 

我要捐贈: 點擊捐贈

Cocos2d-X源碼下載:點我傳送


構造方法
出於初始化類中的成員變數的需要, 可以提供一個方法用於此目的, 這個方法就叫構造方法或構造方法(Constructor)。 與C++和Java不同, Objective-C命名是沒有限制的, 並且有返回值本身類型指標。
以音樂類舉例:Song.h檔案
@interface Song : NSObject {NSString *title;NSString *artist;long int duration;}//操作方法- (void)start;- (void)stop;- (void)seek:(long int)time;//訪問成員變數方法@property(nonatomic,retain) NSString *title;@property(nonatomic,retain) NSString *artist;@property(readwrite) long int duration;//構造方法-(Song*) initWithTitle: (NSString *) newTitleandArtist: (NSString *) newArtistandDuration:( long int ) newDuration;@end
在Song類的定義中添加了一個方法, 它一般用 init開頭命名, 它的返回值很特殊, 是返回值本身類型指標。 並且有返回值本身類型指標。
實現代碼如下:
@implementation Song@synthesize title;@synthesize artist;@synthesize duration;//構造方法-(Song*) initWithTitle: (NSString *) newTitleandArtist: (NSString *) newArtistandDuration:(long int) newDuration {self = [super init];if ( self ) {self.title = newTitle;self.artist = newArtist;self.duration = newDuration;}return self;}... ...@end
代碼說明:
1、標頭檔引用規則匯入的檔案要用一對引號引起來,而不是<Foundation/Foundation.h>中的“<”和">"字元。雙引號適用於本地檔案(你自己建立的檔案),而不是系統檔案,這樣就通知編譯器在哪裡能夠找到指定的檔案。2、構造方法的實現代碼幾乎就是模式代碼, 基本上都是如下寫法: 
-(id)init{    self = [super init];    if (self) {        //初始化代碼    }    return self;}
其中使用 [super init] 來調用父類預設構造方法。 

對象的初始化的常見的編程習慣是類中所有的初始化方法都以init開頭。

如果希望在類對象初始化時做一些事情。可以通過覆寫init方法達到這個目的。

這個方法返回的執行個體對象指派給另一新個關鍵詞: self。 self很像 C++ 和 Java 的 this。 
3、還有if ( self ) 跟 ( self != nil ) 一樣, 是為了確定調用父類構造方法成功返回了一個新對象。 當初始設定變數以後, 用返回self 的方式來獲得自己的地址。 
4、父類預設構造方法 -(id) init。 技術上來說, Objective-C中的構造方法就是一個 "init" 開頭的方法, 而不像 C++ 與Java 有特殊的結構。
5、必須將父類init方法的執行結果賦值給self,因為初始化過程改變了對象在記憶體中的位置(意味著引用將要改變)。如果父類的初始化過程成功,返回的值是非空的,通過if語句可以驗證,注釋說明可以在這個代碼塊的位置放入自訂的初始化代碼。通常可以在這個位置建立並初始化執行個體變數。

注意,

init被定義為返回id類型,這是編寫可能會被繼承的類init方法的一般規則。

程式開始執行時,它向所有的類發送initialize調用方法。

如果存在一個類及相關的子類,則父類首先得到這條訊息。

該訊息只向每個類發送一次,並且向該類發送其它任何訊息之前,保證向其發送初始化訊息。


執行個體成員變數範圍限定符

在介面中聲明的執行個體變數可以通過子類進行繼承。

可以把下面指令放在執行個體變數之前,以便更精確地控制其範圍:

即便從封裝的角度出發, 執行個體成員變數應該定義為@private, 但作為一種物件導向的語言, Objective-C支援@public、 @private和@protected範圍限定。 如果一個執行個體變數沒有任何的範圍限定的話, 那麼預設就是@protected。
•@public範圍限定的執行個體變數,可以被本類、其他類或者模組中定義的方法直接存取,即可在任何情況下訪問; 
•@private範圍限定的執行個體變數,只能在這個類裡面才可以訪問;在實現部分定義的執行個體變數預設屬於這種範圍。
•@protected範圍限定的執行個體變數, 可以在這個類裡面和這個類的派生子類裡面可以訪問這個變數,在類外的訪問是不推薦的, 但也可以訪問。在介面部分定義的執行個體變數預設是這種範圍。•@package,對於64位映像,可以在實現該類的映像中的任何地方訪問這個執行個體變數。
@public指令使得其他方法或函數可以通過使用指標運算子(->)訪問執行個體變數。但執行個體變數聲明為public並不是良好的編程習慣,因為這違背了資料封裝的思想(即一個類需要隱藏它的執行個體變數)。

以一個簡單的例子說明範圍:訪問定義如下:
#import <Foundation/NSObject.h>@interface Access: NSObject {@publicint publicVar;@privateint privateVar;@protectedint protectedVar;}@end
調用的main函數如下:
#import <Foundation/Foundation.h>#import "Access.h"int main (int argc, const char * argv[]) {Access *a = [[Access alloc] init];a->publicVar = 5;NSLog(@"public var: %i\n", a->publicVar);a->protectedVar = 6;NSLog(@"protectedVar var: %i\n", a->protectedVar);//不能編譯//a->privateVar = 10;//NSLog(@"private var: %i\n", a->privateVar);    return 0;}
注意:@public、 @private和@protected範圍限定只能修飾的執行個體成員變數, 不能修飾類變數, 更不能修飾方法。

什麼是類變數和類方法

再以一個簡單的例子說明下:

ClassA.h檔案

#import <Foundation/NSObject.h>static int count;@interface ClassA: NSObject {int aaa;}+(int) initCount;+(void) initialize;@end

ClassA.m檔案

#import "ClassA.h"@implementation ClassA-(id) init {self = [super init];count++;return self;}+(int) initCount {return count;}+(void) initialize {count = 0;}@end

代碼說明:init方法是預設構造方法, 在這個構造方法中累計類變數count, 在執行個體方法中可以訪問類變數的, 但是類方法不能訪問執行個體變數。 initCount 方法是一個普通的類方法, 用於返回類變數count, initialize方法是非常特殊的類方法,它是在類第一次訪問時候被自動調用 , 因此它一般用來初始化類變數的, 類似於C#中的靜態構造方法。

調用的main函數
#import <Foundation/Foundation.h>#import "ClassA.h"int main( int argc, const char *argv[] ) {ClassA *c1 = [[ClassA alloc] init];ClassA *c2 = [[ClassA alloc] init];// print countNSLog(@"ClassA count: %i", [ClassA initCount] );ClassA *c3 = [[ClassA alloc] init];NSLog(@"ClassA count: %i", [ClassA initCount] );[c1 release];[c2 release];[c3 release];return 0;}
代碼說明:

在第一次執行個體化ClassA時候會調用兩個方法: 

initialize類方法和執行個體構造方法init, 

然後再次執行個體化ClassA時候只是調用執行個體構造方法init, 而沒有調用 initialize類方法。 
這樣類變數count被一直累加, 它隸屬類;

因此c1 執行個體可以訪問, c2和c3都可以訪問。

關於屬性、儲存方法和執行個體變數:

編碼規範(Xcode4已經採用的)目前的趨勢是使用底線(_)作為執行個體變數名的起始字元。

@synthesize window = _window;

表明合成(synthesize)屬性window的取值方法和設定方法,

並將屬性與執行個體變數_window(執行個體變數並沒有顯性聲明)關聯起來。

這對區別屬性和執行個體變數的使用是有協助的。

[window makeKeyAndVisible]; //錯誤

[_window makeKeyAndVisible];//正確

[self.window makeKeyAndVisible];//正確


全域變數:

在程式的開始處(所有的方法、類定義)編寫一下語句:

int gMoveNumber = 0;

那麼這個模組中的任何位置都可以引用這個變數的值。

這種情況下,我們說gMoveNumber被定義為全域變數。

按照慣例,用小寫g作為全域變數的首字母。

外部變數是可被其他任何方法或函數訪問和更改其值的變數。

在需要訪問外部變數的模組中,變數聲明和普通方式一樣,只是需要在聲明前加上關鍵字extern。


使用外部變數時,必須遵循下面這條重要的原則:變數必須定義在源檔案中的某個位置。

即在所有的方法和函數之外聲明變數,並且前面不加關鍵字extern,如:int gMoveNumber;

確定外部變數的第二種方式是在所有的函數之外聲明變數,

在聲明前面加上關鍵字extern,同時顯式地為變數指派初始值。


記住,聲明不會引起分配變數的記憶體空間,而定義會引起變數記憶體空間分配。

處理外部變數時,變數可以在許多地方聲明為extern,但是只能定義一次。

注意,如果變數定義在包含訪問該變數的檔案中,那麼不需要單獨進行extern聲明。


靜態變數:

在方法之外定義的變數不僅是全域變數,而且是外部變數。

如果希望定義全域變數且只在特定模組(檔案)中是全域的,就可以使用static來修飾。


注意,重載alloc並不是好的編程實踐,因為這個方法處理記憶體的物理分配。


列舉資料型別:

列舉資料型別的定義以關鍵字enum開頭,之後是列舉資料型別的名稱,然後是標識符序列(包含在一對花括弧內),它們定義了可以給該類型指派的所以的允許值。

在代碼中定義的枚舉類型的範圍限於塊的內部。

另外,在程式的開始及所有塊之外定義的列舉資料型別對於該檔案是全域的。

定義列舉資料型別時,必須確保枚舉標識符與定義在相同範圍之內的變數名和其他標識符不同。


Objective-c 類變數

是不是這樣的?
@interface Member (){
UIImageView *ImageView;
}
@end

@implementation Member

這個變數是類變數,但是是私人的,範圍是當前這個類,如果外界要調用的話,只能通過介面函數,不能直接“.”到
 
objective-c類成員函數與成員變數的訪問性問題

方法是沒有存取層級的,跟ObjectiveC跟C(不是C++)是類似的。
C裡面定義了方法,但是如果不給出聲明,別人調用時候是找不到的(雖然自己聲明一個一模一樣的方法也可以)。ObjectiveC也是一樣,所有方法都沒有訪問保護層級(@property屬性也是方法的一種)
只有一種有存取層級,就是大括弧裡面定義的成員變數,裡面有public和private,貌似是沒有protected的概念(可能有,但是我完全不用的)。
ObjectiveC 2.0以上已經很少需要自己定義成員變數了。@synthesize指令能根據@property自動產生一個私人的成員變數。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.