2010-08-27 44 views
1

我有一個對象將一個本地字符串附加到另一個,然後將它交給一個實例變量。這個StringObj被調用的UITableViewController持有。在第一次調用時,fullCmdString具有正確的字符串。但是,在第二次調用時,fullCmdString爲空,或者充滿奇怪的數據(看起來像奇數mem位置中的數據)。我最好的猜測是stringByAppendingString返回的是對inStr的引用,而不是新的NSString對象,所以數據超出了範圍。任何人都可以對此有所瞭解嗎?奇怪的NSString stringByAppendingString行爲

#import "StringObj.h" 

@synthesize fullCmdString; 

- (void)assemble:(NSString *)inStr { 
    NSString *add = @"text added"; 

    //doesn't hold onto string 
    fullCmdString = [NSString stringWithString:[inStr stringByAppendingString:add]]; 

    //doesn't hold onto string either 
    fullCmdString = [inStr stringByAppendingString:add]; 

    //works great 
    fullCmdString = @"basic text text added"; 

} 

回答

1
// creates an autoreleased string 
fullCmdString = [NSString stringWithString:[inStr stringByAppendingString:add]]; 

// also creates an autoreleased string 
fullCmdString = [inStr stringByAppendingString:add]; 

// works great, not an autoreleased string 
fullCmdString = @"basic text text added"; 

一個autoreleased字符串被在運行循環迭代結束時發送一個release消息(連同在自動釋放池一切)。如果你希望它生存的運行循環迭代,避免把它在自動釋放池,或者明確地保留它:

// OK! Avoid the autorelease pool (at least, for fullCmdString) 
fullCmdString = [[NSString alloc] initWithString:[inStr stringByAppendingString:add]]; 

// also OK! It's in the pool, but it's also been retained. 
fullCmdString = [[inStr stringByAppendingString:add] retain]; 

// also OK 
fullCmdString = @"basic text text added"; 

見可可memory management rules以獲取更多信息。本指南將告訴您,您已明確分配或保留的任何內容(如上面的—),您在完成操作後也必須明確釋放。

+0

這對運行循環自動釋放字符串是有意義的。我想我會在本週末討論蘋果內存管理文檔。謝謝! – John 2010-08-27 04:42:13

1

你需要保留它:否則會在當前範圍的年底發佈,作爲stringByAppendingString返回一個自動釋放的對象。

請閱讀可可內存管理指南。

2

可可內存管理不涉及範圍。一個物體的生命或死亡取決於所有權 - 如果另一個物體擁有它(通過創建該物體的方式爲alloc,newcopy,或聲稱擁有retain),它會停留在周圍。當物體沒有更多的主人時,它可以消失。在你的情況下,你想保留在fullCmdString附近的NSString對象,但是你沒有做任何事情來聲明它的所有權,所以它只是靜靜地消失併成爲垃圾指針。

我強烈建議您閱讀Apple的memory management rules。這是一套非常簡單的指導方針,但是它使得工作程序和具有這種奇怪錯誤的程序之間有所不同。

+0

不完全正確。您的初始聲明假定應用中的所有其他代碼正常運行。一個對象擁有/保留的對象很可能被另一個可能或不可能擁有它的對象所釋放。在調試未知質量的代碼時,意識到這一點是必需的(例如,在幾個啤酒後深夜編碼時,也許是你自己的:)。 – hotpaw2 2010-08-27 06:31:45

+0

@ hotpaw2:這與我說的任何東西都不矛盾。如果有人過度釋放它,這違反了內存管理合同。 – Chuck 2010-08-27 14:04:19