2013-03-13 106 views
0
+ (id)packetWithType:(PacketType)packetType 
{ 
    return [[[self class] alloc] initWithType:packetType]; 
} 

- (id)initWithType:(PacketType)packetType 
{ 
    if ((self = [super init])) 
    { 
     // code 
    } 
    return self; 
} 

爲什麼我們需要第一類方法,是不是第二個只是初始化?Objective C類初始化

+0

第一個也是'alloc'部分......而不是它有一個「+」而不是「 - 」。 – Larme 2013-03-13 10:13:30

+0

請注意,您通常會從類方法初始值設定項返回自動釋放對象,這是每個人都期望的。 – 2013-03-13 10:18:07

+0

正在返回一個與ARC相關的自動發佈的對象嗎? – colincameron 2013-03-13 10:20:07

回答

6

有便利構造函數類方法的兩個原因。第一個是,[[Thing alloc] initWithFoo: xyz]的成語非常普遍,但不便隨處輸入。所以,[Thing thingWithFoo: xzy]是一個常用的縮寫。

更深層次的原因與引用計數有關。以init開頭的方法應該返回實例的引用,其所有權轉移給調用者。 Wheras方便類方法通常返回autorelease d引用:

+ (id)packetWithType:(PacketType)packetType 
{ 
    return [[[[self class] alloc] initWithType:packetType] autorelease]; 
} 

這一點很重要,以避免懸掛引用和/或內存泄漏知道:

Thing* thing = [[Thing alloc] initWithFoo: xyz]; 
// Now, *I* own the reference and *I* am responsible for releasing 
// it, when I no longer need it. 
[thing release] 

在另一方面,引用返回通過

Thing* thing = [Thing thingWithFoo: xyz]; 

歸屬於「最近的」NSAutoreleasePool。調用者不負責釋放它(事實上,這將是錯誤的!)。如果引用是要圍繞保持,調用者必須是實際retain在這裏:

self->myMember = [thing retain]; 

您應該瞭解這些約定使用ARC即使作爲基本規則仍然有效,即使(ARC下)它是編譯器,它生成遵守它們的代碼。 NARC首字母縮略詞是一種很好記住的方法,哪種方法名稱前綴帶有某些責任。 This answer has the details

1

由於某些原因,便捷構造函數在語言中佔有一席之地。當然,使用它們通常更短,但還有其他優點:

  1. 對象在調用時尚未分配,因此該方法可以決定分配哪個類。類簇可能會根據構造函數的參數使用它來查找適當的類。
  2. 該方法也可能決定從共享緩存中返回一個已經存在的對象。
  3. 返回值可以是靜態類型。

請注意,您的便捷構造通常會是:

+ (Packet *)packetWithType:(PacketType)packetType 
{ 
    return [[self alloc] initWithType:packetType]; 
} 

現在的返回類型是靜態類型的,我們不發送(冗餘)class消息對類對象。使用最近的編譯器版本,可以使用instancetype作爲返回類型。

+0

+1。我完成了,忘記了類集羣。好決定。 – Dirk 2013-03-13 12:48:50