ObjctiveC还有另一个retain-copy-release错误

时间:2011-08-03 21:02:45

标签: iphone objective-c ios

  

可能重复:
  Objective C alloc/release error

当我尝试下面的代码时,如果我发布newString,它会崩溃并使用BAD_ACCESS。我在这里缺少什么?

据我所知,当我使用“copy”作为访问器时,我获得了对象的所有权,所以即使我释放其他引用指针,保留计数仍应保持1+,因此该对象仍然应该是在记忆中?

P.S。如果它有所不同,这是一个单例类。

.h文件

NSString *originalString;
@property (nonatomic,copy) NSString *originalString;

.m文件

@synthesize originalString;
...
NSString *newString = [[NSString alloc] init...];
self.originalString = newString;
[newString release];  //this lines makes it crash

我也试过

self.originalString = [newString copy];

没有运气..

5 个答案:

答案 0 :(得分:1)

您是否尝试过使用retain代替copy

http://wiki.cs.unh.edu/wiki/index.php/Objective_C_Property_Attributes#Setter_Semantics

如果复制没有,我不确定这是否真的有用,但是使用retain代替copy会导致字符串的引用计数在分配时增加1对于属性,从字符串alloc编辑时的1开始将其提高到2,因此当在属性赋值后在行上使用[newString release];时,字符串应该以引用计数结束1并因此继续存在。

答案 1 :(得分:1)

[newString relase]; //this lines makes it crash

relase可能不是方法的名称。您的意思是release吗?

假设上述问题只是您的问题中的印刷错误,而不是代码中的错误,那么您的代码是正确的,并且您需要提供有关错误的更多信息。在这种情况下,粘贴相关方法的实际代码会很有用。

答案 2 :(得分:1)

这段代码看起来是正确的,你确定崩溃不在其他地方吗?


编辑:如评论中所述,NSString是不可变的,不会导致copy分配新对象。我已经编辑了可变案例的答案,以防万一有人在以后遇到这种情况并且没有读完整个事情。 现在回到我们的常规编程。


不知道这可能是问题所在,但请注意,如果您使用像NSMutableString这样的可变对象,而copy不会增加保留计数,那么您将有效地创建一个新对象,那会发生什么:

NSMutableString* newString = [[NSMutableString alloc] init..]; // allocate a new mutable string
self.originalString=newString; // this will create yet another string object
// so at this point you have 2 string objects.

[newString relase];  //this will in fact dealloc the first object
// so now you have a new object stored in originalString, but the object pointed
// to by newString is no longer in memory.
// if you try to use newString here instead of self.originalString,
// it can indeed crash.

// after you release something, it's a good idea to set it to nil to
// avoid that kind of thing
newString = nil;

答案 3 :(得分:0)

您可以考虑使用ARC将代码迁移到Xcode 4.1,然后您不必担心保留和释放对象。

答案 4 :(得分:0)

您是否尝试过将自动释放添加到* newString init?然后一起拿出手册。

NSString *newString = [[NSString alloc] init...] autorelease];