簡體   English   中英

是否有必要在 alloc 語句中設置 autorelease?

[英]Is it necessary to set autorelease within alloc statement?

假設以下代碼,

NSString *str=[[NSString alloc] initWithString:@"sagar"];


[str autorelease];

我已經多次看到,大多數程序員確實更喜歡將allocinit同時放在一個語句中。

在這里,我要求將 autorelease 划分為下一個語句的可能性。

  • 例如,建議將 init 與 alloc 語句放在一起。 自動釋放也一樣嗎?

大多數程序員確實更喜歡將 alloc、init 同時放在一個語句中。

這是因為初始化程序返回的實例不一定是+alloc返回的實例。 例如,這是錯誤的,會導致程序崩潰:

NSString *str = [NSString alloc];
[str initWithString:@"sagar"];

因為在這種情況下-initWithString:導致前一個實例的釋放,而str最終指向一個釋放的 object。 這可以通過以下方式解決:

NSString *str = [NSString alloc];
str = [str initWithString:@"sagar"];

這樣str指向-initWithString:返回的不同實例。 表格:

NSString *str = [[NSString alloc] initWithString:@"sagar"];

保證str指向正確的實例。


也就是說, -autorelease是不同的。 除非它被邪惡的 djinn 覆蓋,否則它總是返回接收器本身。 這意味着兩者:

NSString *str = [[NSString alloc] initWithString:@"sagar"];
str = [str autorelease];

和:

NSString *str = [[NSString alloc] initWithString:@"sagar"];
[str autorelease];

是正確的並且以相同的方式工作。

至於區別:

NSString *str = [[[NSString alloc] initWithString:@"sagar"] autorelease];

和:

NSString *str = [[NSString alloc] initWithString:@"sagar"];
…
[str autorelease];

有些人更喜歡將-autorelease與分配一起使用,以避免稍后忘記自動釋放實例。 其他人更喜歡將其放在return語句中(如果有的話):

NSString *str = [[NSString alloc] initWithString:@"sagar"];
…
return [str autorelease];

使(更)明確的方法/函數返回一個自動發布的 object。

你可以在 scope 的任何地方使用自動釋放,實際上最常見的用法是

return [object autorelease]

當您想將 object 返回給調用者時。

你可以這樣做

MyObject* foo = [[MyObject alloc] init];
...
[foo autorelease];
...
return foo;

或這個

MyObject* foo = [[MyObject alloc] init];
...
...
return [foo autorelease];

或這個

MyObject* foo = [[[MyObject alloc] init] autorelease];
...
...
return foo;

我會用第二個或第三個 go ,但這是個人喜好。

如果是臨時的 object 你不退貨,你可以這樣做:

MyObject* foo = [[MyObject alloc] init];
...
[foo autorelease];
...
return somethingElse;  

或這個

MyObject* foo = [[[MyObject alloc] init] autorelease];
...
...
return somethingElse;    

或這個

MyObject* foo = [[MyObject alloc] init];
...
[foo release];
...
return somethingElse;  

在這種情況下,我認為您不會看到第一個選項。 畢竟,當您也可以發布時,為什么還要自動發布。 您經常看到第二個選項。 這意味着您不必記住稍后再發布。 您還經常看到第三個選項。 它在 iOS 上的優勢在於不會長時間持有不需要的 memory。

是的,您可以在下一條語句中放入 autorelease,但是此 str 的 scope 將是本地的,當控制超出 scope 時,此字符串將被釋放....

如果您將autorelease放在下一個語句中,則不是問題。

當 object 的 scope 結束時,自動釋放object 會自動放入自動釋放池中。 意味着,當 object 的 scope 結束時,編譯器會自動添加發布消息,在這種情況下,您不必為該 object 編寫發布消息。 自動釋放池存儲在池本身耗盡時發送釋放消息的對象。

Application Kit 在事件循環的每個循環開始時在主線程上創建一個自動釋放池,並在結束時將其排出,從而釋放在處理事件時生成的任何自動釋放對象。 如果您使用 Application Kit,您通常不必創建自己的池。 但是,如果您的應用程序在事件循環中創建了大量臨時自動釋放對象,則創建“本地”自動釋放池以幫助最小化峰值 memory 占用空間可能是有益的。

在主線程上, [myObj autorelease]將在特定事件循環結束時自動將 myObj 放入池中,由系統本身管理。 但是,要在輔助線程的情況下使用[myObj autorelease] ,您必須使用 NSAutoreleasePool。 否則,如果池不可用,則不會釋放自動釋放的對象,並且您會泄漏 memory。

例如,對於輔助線程:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// Code benefitting from a local autorelease pool.

[pool release];

請記住,在池本身已釋放后,切勿釋放 object。 這將導致崩潰或任何意外的 output。 我提到這一點是因為,我為犯這個錯誤付出了巨大的代價。

如果你的項目是在 ARC 下開發的,你就不用再擔心retain、release、autorelease了。 Apple 建議使用 ARC 環境。

暫無
暫無

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

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