2011-08-15 127 views
1

我遇到了一些不熟悉的Objective-c內存管理代碼。是什麼區別:Objective-c對象釋放模式

// no property declared for myMemberVariable in interface 
id oldID = myMemberVariable; 
myMemberVariable = [MyMemberVariable alloc] init]; 
[oldID release]; 

和:

// (nonatomic, retain) property is declared for myMemberVariable in interface 
self.myMemberVariable = [[MyMemberVariable alloc] init]; 

謝謝!

回答

4

第二個在技術上是不正確的,但第一個可能源於某人尚未擁抱Objective-C 2.0屬性語法。如果您是一位長期的OS X開發人員(或者甚至是更長時間的NextStep/OS X開發人員),那麼最近添加了這個功能,所以您確實看到人們在沒有獲得任何好處或不利的情況下不會使用它。

所以第一個是基本相同:

[myMemberVariable release]; 
myMemberVariable = [[MyMemberVariable alloc] init]; 

假設你有一個「保留」屬性,正確版本的制定者應該是:

// this'll be retained by the setter, so we don't want to own what we pass in 
self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease]; 
3

在第一個例子中,你有一個實例變量。第二種是具有自動內存管理屬性的屬性(如保留所示)。

在第一個示例中,您將分配一個對象,將其分配給一個實例變量,然後釋放它。由於您沒有明確釋放它,因此您似乎也泄露了以前分配給它的對象。 (也許它是autoreleased,不能告訴這裏)。

在第二個示例中,您將分配一個對象並將其分配給保留該對象的屬性。這意味着你會泄漏它,除非你明確地釋放/ autorelease它。

self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease]; 

MyMemberVariable *m = [[MyMemberVariable alloc] init]; 
self.myMemberVariable = m; 
[m release]; 

這是更好的爲你(大部分)的內存管理的免費使用性質。例如,在分配新參考資料之前,您不必擔心釋放參考資料。

1

第一種形式呢不使用屬性。我沒有看到一個很好的理由不這樣做:

[myMemberVariable release]; 
myMemberVariable = [[MyClass alloc] init]; 

由於舊的價值肯定是不一樣的新,所以沒有機會,纔可以再次被保存的任何舊值被釋放。

屬性的優點是,在較新的編譯器中,它們由編譯器合成並簡單地做正確的事情,即他們知道如何保留新的並釋放舊值,如果該類型是必須保留的類型或複製。這對int,float等類型不是必需的,因爲這些是簡單的值類型。

換句話說,如果您使用點符號,無論是在自己還是在其他對象上,都可以訪問該屬性,實際上根據賦值方向調用getter或setter方法。

如果您直接訪問ivar(成員變量),那麼您不具有該屬性的保護,並且必須自己編寫保留/釋放代碼。

你也可以編寫你自己的setters和getters,然後你也必須照顧內存管理,它適用。不過,它確實給你更多的靈活性。您可以記錄項目,檢查輸入的有效性,更新內部狀態變量等。