2011-12-26 96 views
0

我對自定義初始化方法自動釋放對象的原理有些困惑。例如:在自定義初始化方法中自動釋放

- (id)initWithId: (unsigned long)personID { 
    self = [super init]; 
    if (self) { 
     self.ID = personID; 
    } 

    return self; 
} 

根據objc編碼約定,我必須在返回時自動釋放自我。但是那種代碼不斷破碎。我錯過了什麼嗎?我應該自動釋放這些方法手動創建的對象,但不是「自己」,像這樣?

- (id)makeWithId: (unsigned long)personID { 
    Person *obj = [[Person init] alloc]; 

    if (obj) { 
     obj.ID = personID; 
    } 

    return [obj autorelease]; 
} 

在此先感謝。

+1

你是否堅持在調用代碼中返回的對象? – Abizern 2011-12-26 16:55:24

+0

這沒關係=)這都是關於autorelease的原理。我的意思是:如果我調用'SomeClass sc = [SomeClass alloc] init];'我在使用它後肯定會釋放sc。但如果我調用'SomeClass sc = [[SomeClass alloc] initWithSomeParam:123]'我不需要釋放它,我不負責它(initWithSomeParam是)。 – Stormherz 2011-12-26 17:06:47

+4

@Stormherz,你錯了。如果你調用了'alloc',你有責任釋放它。如果你已經調用過'[SomeClass someClassWithSomeParam:5]',那麼你不需要負責它,它是自動釋放的。 – joerick 2011-12-26 17:11:12

回答

3

在Cocoa中,有這樣的約定:

  • 方法與alloc啓動或new返回與保持數+1
  • 是創建一個對象返回一個自動釋放對象的所有其他方法的對象。

請注意,使用上面發佈的init方法,不會創建對象。以前的alloc調用會創建該對象。這只是設置並準備好使用。

至於你的makeWithId方法,你已經混淆了兩個概念。像這樣的工廠方法應該是類方法(即用+聲明,而不是-)。這時你會使用它像

Person *p = [Person makeWithId:3]; 

既然這樣,你比方法調用的返回接收器不同的對象。這意味着,當你做

Person *p = [[Person alloc] makeWithId:3]; 

alloc創建Person對象已被泄露,並p會被自動釋放。

因此,總結一下,從類「工廠」方法返回自動釋放對象,並且不要在init方法中執行任何內存管理。

+0

arghhh,我沒有在這裏分配任何東西,我的空頭,我肯定這次是過度勞累=)非常感謝,現在都是有道理的。 – Stormherz 2011-12-26 17:11:37

2

你不分配任何東西,所以你不必發佈一些東西。

您可以在創建對象時自動釋放對象。

YourClass *yourOblect = [YourClass alloc] initWithId:27] autorelease]; 
[yourObject doSomething]; 
..... 
+0

謝謝,我現在明白了=) – Stormherz 2011-12-26 17:13:46