2009-08-19 110 views
0

我有一些代碼,導致EXC_BAD_ACCESS錯誤:內存問題

recordIDAsString = [ 
    NSString stringWithFormat:@"%i", (int)abRecord.recordID 
]; 
propertyIDAsString = [ 
    NSString stringWithFormat:@"%i", (int)abProperty.propertyID 
]; 
identifierAsString = [ 
    NSString stringWithFormat:@"%i", (int)abProperty.identifier 
]; 

recordIDAsString,propertyIDAsString和identifierAsString在界面中的所有定義。該代碼包含在編輯視圖控制器中,並且三個* AsString變量似乎工作正常,直到按下保存按鈕時,其值變得無效。然而,我發現下面的代碼不工作:

NSString *tempRecordIDAsString = [ 
    NSString stringWithFormat:@"%i", (int)abRecord.recordID 
]; 
NSString *tempPropertyIDAsString = [ 
    NSString stringWithFormat:@"%i", (int)abProperty.propertyID 
]; 
NSString *tempIdentifierAsString = [ 
    NSString stringWithFormat:@"%i", (int)abProperty.identifier 
]; 

recordIDAsString = [tempRecordIDAsString copy]; 
propertyIDAsString = [tempPropertyIDAsString copy]; 
identifierAsString = [tempIdentifierAsString copy]; 

我想我只有當我打電話的alloc或init,所以我的問題是管理內存:什麼是導致第一個代碼示例發生內存變得無效?

+1

這是一些嚴重奇怪的方法調用格式...但是,對於他自己。 – bbum 2009-08-19 01:02:08

+1

是的,它格式非常奇怪。這是誤導性的,因爲它使得發送給對象的消息看起來像代碼括號。 – corydoras 2009-08-19 04:15:09

+0

你怎麼做才能在多行中打破這個信息? – JoBu1324 2009-08-21 09:19:21

回答

3

通過創建一個字符串...

[NSString stringWithFormat:@"%i", (int)abRecord.recordID] 

...會被自動釋放。除非你保留它,否則它會在下一個autorelease池中排出。

你需要重新審視的內存管理指南:

http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

+0

,因爲我在獲取它們的值後不需要臨時字符串,如果我馬上釋放它們,最好還是等待autorelease池-drain? – JoBu1324 2009-08-19 02:22:10

+1

因爲stringWithFormat會自動釋放,所以你不應該釋放。請參閱上面列出的內存管理指南。如果您擁有copy,retain,alloc的所有權,則只應釋放。你沒有這樣做,所以你應該讓autorelease池做它的事情。但是,您可以使用[[NSString alloc] initWithFormat:],然後在完成時釋放該字符串。 - 儘管你可以簡單地執行recordIDAsString = [[NSString alloc] initWithFormat:],然後你只需釋放dealloc,因爲它看起來像recordIDAsString是一個實例變量。 – Brian 2009-08-19 02:28:47

2

的NSString stringWithFormat是一個有用的構造方法 - 這意味着它會返回的對象會被自動釋放,這樣你就不必這樣做。導致的問題是,如果您想保留該值,則必須保留或複製該值。所以,即使您存儲對該值的引用,您也不會遞增其retainCount。因此,噹噹前運行循環完成時,autorelease池將向其所有對象發佈釋放,將retainCount減1。如果使用保留,則會將retainCount增加1,以便autorelease釋放該對象時,它將仍然有一個retainCount直到發送另一個版本 - 這應該由你在某個時候完成 - 也許在你的dealloc中。