2010-09-14 75 views
0

當涉及到分配和初始化被聲明我見過的示例代碼的各個位,兩個主要圖案的一類@properties對象,因此給出下面的(由)報頭的代碼 -效益的間接分配和初始化一個聲明@property

@interface Class : Superclass { 
    Object *anObject; 
} 
@property (nonatomic, retain) Object *anObject; 

第一,直接分配:

self.anObject = [[Object alloc] init]; 

第二,間接方法創建一個臨時對象,然後被分配給屬性和釋放:

Object *tempObject = [[Object alloc] init]; 
self.anObject = tempObject; 
[tempObject release]; 

有什麼好處在第一第二的方法?

回答

3

這兩個代碼塊的區別在於第一個代碼是內存泄漏。當您致電[Object alloc]時,您將獲得該物品的「所有權」,並在某個時間負責該物品的所有權。然後當你調用[self -setAnObject]它需要所有權,創下了新的實例保留計數爲2。如果方法做創造回報,而不放棄其新實例的所有權,你結束了泄漏。

試試這個:

self.anObject = [[[Object alloc] init] autorelease];

這工作,因爲[NSObject -autorelease]回報自我,也安排一個-release呼叫「在將來某個時候」,這通常意味着在當前的運行循環的結束。

+0

我真的很驚訝,人們正在認真地提出第一個直接分配方法。 – 2010-09-15 00:07:11

+0

正如hotpaw1提到的,我確實有錯誤的第一個模式 - 我沒有看到任何使用@property setter方法,但我對self.anObject = [...]與anObject = [...]之間的區別模糊不清無論如何。但這是有道理的 - 我忘記了點語法影響保留計數。 – 2010-09-15 03:20:09

2

作爲以前的海報正確地指出,第一種方法(至少它目前編碼方式)是內存泄漏。然而,第二種方法在技術上更高效,因爲與autorelease池有關的開銷。

添加一個額外的對象池可能是不會讓一個可測量的差異,但不必要地增加大量的對象到池可能,所以一般的第二種方法是首選。

2

您可能會錯過第一個模式。直接分配(實例變量)應爲:

anObject = [[Object alloc] init]; 

繞過二傳手,並因此留下的1

適當的保留計數壞事是,它避免了二傳手(從而導致潛在的代碼重用/增強問題)。

的好處是,它避免了二傳手(重要,如果這出現在配置文件的一個熱點)。

+0

你能否解釋一下爲什麼避免二傳手不好和/或好? – 2010-09-15 03:29:52

+0

速度更快,因爲您直接設置內存,而不是發送消息給自己。但是通過避免發送消息,您也可以繞過KVC,屬性觀察器和綁定等所需的運行時魔法。 – Sophistifunk 2010-09-23 11:38:31