簡體   English   中英

沒有明確調用Objective-C版本

[英]Objective-C release is not called explicitly

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

NSString * str = [[NSString alloc] initWithString:@"test"];
[str release];
int i = 999999999;
while(i-- > 0) {}
NSLog(@"%@", str);
[pool drain];

輸出:測試

為什么沒有release工作? 如何立即從內存中刪除對象?

Xcode 4.0版iPhone應用程序


〜〜解決

感謝所有人的回答。 我有很多關於這個問題的有用信息。 我將使用NSString * str = @“text”而不是NSString * str = [[NSString alloc] initWithString:@“text”];

我知道釋放只是“標記”記憶“願意被釋放”,但不能立即釋放它

發布確實有效,但您嘗試執行的操作具有未定義的行為,並且在使用NSString和文字時,您可能也會遇到不同的行為。 發生的事情是,雖然您的對象被釋放,但該位置的內存可以回收並且沒有更改,當它打印時它仍然有效。 由於它是NSString,因此不一定要發送描述消息,這就是為什么在嘗試發送解除分配的對象時沒有獲得異常的原因。

這個問題有一些關於NSString和NSLog的好信息。

它確實有效。 您已放棄該對象的所有權,並且當系統確定它不再擁有時,系統將標記為可供系統重用。 如果您是該字符串的唯一所有者,那可能會立即發生。 如果字符串的創建導致它在內部自動釋放,則可能會在稍后的某個時間點發生。 或者,正如Dave DeLong指出的那樣,系統可能會將其優化為永不釋放的對象。

在您的情況下,它被優化為一個常量字符串,它將在程序的生命周期中存在。 如果您使用NSMutableString而不是NSString ,您會看到可能不會崩潰的時髦行為,但不會打印您所期望的內容。 (請參閱此問題以獲取示例。)

如果您使用NSArray代替,那么當你打電話來釋放release ,但你仍然可以看到您的NSLog例子正確工作,直到你分配一些其他的對象。 釋放只是將內存標記為可重用; 它實際上並沒有清除它。 因此,如果您將數組傳遞給NSLog,則該內存尚未更改,因此仍可正確打印。

但是,所有這一切的關鍵點是要認識到調用release不一定會導致對象被釋放。 它可能因任何原因而繼續存在。 但是一旦你調用release ,你就放棄了對象的所有權。 如果你在那之后繼續使用它,系統可以自由地做各種奇怪的事情,如圖所示。

當你這樣做時:

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

這被優化為:

NSString * str = @"test";

您無法release常量字符串,因為它已硬編碼到應用程序二進制文件中。

證明:

NSString *s = [NSString alloc];
NSLog(@"%p", s);
s = [s initWithString:@"foo"];
NSLog(@"%p", s);
s = @"foo";
NSLog(@"%p", s);

日志:

2011-04-12 10:17:45.591 EmptyFoundation[6679:a0f] 0x100116370
2011-04-12 10:17:45.599 EmptyFoundation[6679:a0f] 0x100009270
2011-04-12 10:17:45.604 EmptyFoundation[6679:a0f] 0x100009270

你可以看到的結果+alloc是從的結果不同 -initWithString:和結果-initWithString:等同於常量字符串。 基本上, -initWithString:說“啊哈,我將成為一個不可變的字符串,我將被賦予一個不可變的字符串!我可以采取一個捷徑,摧毀自己,並返回參數,一切都將繼續工作相同”

您在NSLog()中使用了錯誤的指針。 在這種情況下,您碰巧變得幸運,但您應該期望這樣的代碼在其他方面崩潰或失敗。

無需刪除內存塊,這將耗盡不需要的周期。 當分配新對象占用該內存塊時,將覆蓋內存。

暫無
暫無

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

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