iOS開發學習筆記-建立和初始化對象

來源:互聯網
上載者:User

標籤:

Objective-C中對象的建立和初始化
(Allocating and Initializing Objects)
(主要內容來自於Apple的電子書《The Objective-C Programming Language》的“Allocating and Initializing Objects”。電子書可以從iBooks商店下載。iOS Developer Library也有同名的文檔,但是內容上是不同的。)


在Objective-C中建立對象分為兩步:
1 開闢一個對象所需的記憶體,Allocating object
2 為對象的各個成員賦予初始值,Initializing object

開闢記憶體這個步驟很簡單。一般來說,Objective-C中的所有類都繼承於NSObject。NSObject定義了兩個方法——alloc和allocWithZone:。子類不用重載和修改這兩個方法。直接使用就能開闢建立一個自己子類對象所需的記憶體。

重要的工作在第二步。

初始化對象的方法一般以init開頭,比如無參數的init方法,或者initWithFrame:方法。NSObject類定義了init方法。一般而言,子類需要根據自己需要,定義自己的初始化方法。

初始化方法返回的對象(傳回值)
需要注意的是,初始化方法(init...)的傳回值不一定和該方法的接收者(或者以C語言角度來說是調用者)同類型的對象。如果初始化失敗,返回的對象則是nil。比如依靠一個檔案來初始化對象,如果開啟檔案失敗,那麼返回的對象是nil。
下面的代碼是危險的:
id aObject = [SomeClass alloc];
[aObject init]; //在這裡傳回值不一定就是aObject,
[aObject someOtherMessage]; //實際應該someOtherMessage的接收者應該是init的傳回值,而不是aObject
正確的寫法如下:
id aObject = [SomeClass alloc] init];
[aObject someOtherMessage];


實現初始化方法時需要注意的地方
~方法的名字應該以init開頭
~方法的傳回值類型應該是id
~在實現中需要調用designated initializer(什麼是designated initiailizer後面會提到)。一個類有很多初始化方法,其中一個(或者一些)叫designated initializer(翻譯成?“指定的初始化方法”?)。實現子類的designated initializer時,必須調用父類的designated initializer。實現子類的其他初始化方法時,需要直接或者間接地調用一下自己的designated initializer。
NSObject的designated initializer方法是init。
~在初始化方法裡設定成員變數時不要使用accessor method(存取方法)。
~把初始化方法的傳回值賦給self。
~返回self,或者如果初始化失敗,返回nil。

初始化失敗時的處理
如果失敗返回nil, 另外如有必要對self調用release方法。
- (id) init {
  self = [super init]; //給self賦值; 調用super的designated initializer
  if (self) { //只有super的init返回的值不是nil才做下面的事情
    theDate = [ [NSDate alloc] init];
  }
  return self; //如果失敗返回,self的值是nil,返回的nil
}
另一個例子:
- (id) iniWithImage:(NSImage *) aImage {
  if (aImage == nil) {
    [self release]; //如果傳入的參數有問題,那麼調用self的release方法
    return nil;
  }
  self = [super init_xxx: yyy];
  if (self) {
    image = [aImage retian];
  }
  return self;
}



子類需要確保所有從父類繼承而來的初始化方法都能正確工作。
比如類A定義了init方法;子類B定義了initWithName方法。類B要保證init訊息也能正確地初始化類B。一個簡單的方法是類B的init調用類B的initWithName方法來實現自己:
- init {
  return [self initWithName:"default"];
}


The Designated Initializer
一個類的designated initializer確保所有繼承而來的成員都被初始化(通過調用super的方法),同時也做了其他的大部分工作。這個類的其他初始化方法調用這個designated initializer。
一個類的designated initializer方法必須調用父類的designated initializer,而不是父類的其他初始化方法。如果不這麼做可能會引起死迴圈。
(具體例子見電子書)


合并開闢記憶體和初始化記憶體這兩個步驟(Combine allocation and initialization)
有些類提供了一些方法,在這些方法裡實現了記憶體開闢和記憶體初始化這兩個步驟。這些方法被稱為convenience constructors(便利的建構函式)。一般形式是+className...。
比如NSArray提供了:
+ (id) array;
+ (id) arrayWithObjects:(id) firstObj, ...;
有時候這些方法很有用。比如,+ (id) arrayWithObjects:(id) firstObj, ...,只有知道了參數的個數才能知道應該分配多大的記憶體。所以不能將開闢記憶體和初始化記憶體這兩個步驟分開。
再看下面的例子(singleton),如果對象已有就直接返回已有對象,沒必要開闢記憶體:
+ (Soloist *) soloist {
  static Soloist *instance = nil; //note: static
  if (instance == nil) {
    instance = [self alloc] init];
  }
  return instance;
}
(傳回型別是Soloist *,不是id,在這種情況下是合適的)

iOS開發學習筆記-建立和初始化對象

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.