簡體   English   中英

Objective-c object 釋放模式

[英]Objective-c object releasing patterns

我遇到了一些不熟悉的 Objective-c memory 管理代碼。 有什么區別:

// 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];

謝謝!

第二個在技術上不正確,但第一個可能源於尚未接受 Objective-C 2.0 屬性語法的人。 如果您是長期的 OS X 開發人員(或者甚至更長時間的 NextStep/OS X 開發人員),它是最近才添加的,所以您確實看到人們不使用它而不會因為不這樣做而獲得任何好處或損害。

所以第一個基本相同:

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

鑒於您有一個“保留”屬性,使用 setter 的正確版本應該是:

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

在第一個示例中,您有一個實例變量。 在第二個中,具有自動 memory 管理屬性的屬性(如保留所示)。

在第一個示例中,您分配了 object,將其分配給實例變量,然后釋放它。 您似乎還泄漏了之前分配給它的 object,因為您沒有明確釋放它。 (也許它是自動發布的,在這里無法判斷)。

在第二個示例中,您正在分配 object,並將其分配給保留它的屬性。 這意味着除非您明確釋放/自動釋放它,否則您將泄漏它。

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

或者

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

當您免費獲得(大多數)memory 管理時,最好使用屬性。 例如,您不必擔心在分配新引用之前釋放引用。

第一種形式不使用屬性。 我認為沒有充分的理由不這樣做:

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

由於舊值與新值肯定不一樣,所以在再次保留之前,不可能釋放任何舊值。

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

換句話說,如果您在 self 或其他 object 上使用點表示法,您將訪問該屬性並實際上調用 getter 或 setter 方法,具體取決於分配的方向。

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

您還可以編寫自己的 setter 和 getter,然后您還必須處理適用的 memory 管理。 但是,它確實為您提供了更大的靈活性。 您可以記錄項目、檢查輸入的有效性、更新內部 state 變量等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM