2010-02-18 148 views
5

鑑於以下屬性定義:Objective-C的性能和內存管理

@property (nonatomic,retain) MyObject* foo; 

沒有下面的代碼會導致內存泄漏:

self.foo = [[MyObject alloc] init]; 

看起來像alloc調用將對象上的保留計數遞增到1,然後屬性設置器中的保留將其增加到1.但是由於初始計數永遠不會遞減爲0,因此即使在自我釋放。分析是否正確?

如果是這樣,它看起來像我有兩個選擇:不推薦在iPhone上由於性能原因,或

self.foo = [[[MyObject alloc] init] autorelease]; 

MyObject* x = [[MyObject alloc] init]; 
self.foo = x 
[x release]; 

這是一個有點麻煩。還有其他的選擇嗎?

回答

2

你是對的,self.foo = [[MyObject alloc] init];正在泄漏內存。兩種選擇都是正確的,可以使用。關於autorelease這樣的聲明:請記住,一旦當前運行循環結束,該對象將由autorelease池釋放,但它很可能會被self保留很長時間,因此內存使用沒有問題尖峯在這裏。

3

有沒有其他的選擇?

你是不是要能寫多少的iPhone應用程序,而無需使用自動釋放和可可觸摸庫使用他們在很多地方號。瞭解它正在做什麼(將指針添加到下一幀的清除列表中)並避免在緊密循環中使用它。

你可以在MyObject上使用class方法來爲你進行alloc/init/autorelease清理工作。

+ (MyObject *)object { 
    return [[[MyObject alloc] init] autorelease]; 
} 

self.foo = [MyObject object]; 
+0

這是一個很好的選擇,可以在創建實例時節省時間。 – 2010-02-18 23:05:56

3

在iPhone上管理留置財產的最簡單方法如下(你想的自動釋放是不是那麼糟糕,至少對於大多數用途):

-(id)init { 
    if (self = [super init]) { 
     self.someObject = [[[Object alloc] init] autorelease]; 
    } 
    return self; 
} 

-(void)dealloc { 
    [someObject release]; 
    [super dealloc]; 
} 

autorelease釋放參考到分配給self.object的浮動實例,該實例保留其自己的參考,從而爲您提供所需的一個參考(someObject)。然後當這個類被銷燬時,剩下的唯一引用被釋放,銷燬這個對象。

正如另一個答案中所述,您還可以創建一個或多個「構造函數」消息來創建和自動釋放具有可選參數的對象。

+(Object)object; 
+(Object)objectWithCount:(int)count; 
+(Object)objectFromFile:(NSString *)path; 

人們可以定義這些爲:

// No need to release o if fails because its already autoreleased 
+(Object)objectFromFile:(NSString *)path { 
    Object *o = [[[Object alloc] init] autorelease]; 
    if (![o loadFromFile:path]) { 
     return nil; 
    } 
    return o; 
} 
+0

-1不會調用'[super init]'和'[super dealloc]',這很危險。 – MrMage 2010-02-18 23:11:19

+0

我的錯誤,我只是指出someObject的分配方法。代碼已更新。 – 2010-02-18 23:13:08

+0

這仍然是錯誤的,事實上'init'方法涉及將'[super init]'的返回值賦給'self'。 – dreamlax 2010-02-19 00:58:47