2009-08-19 126 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中。