3

这是我的 iPhone 代码的(非常)简化版本:

@interface x {
NSString * name1;
NSString * name2;
}

-init {
name1 = @"";
name2 = @"";
}

-(void) a {
Foo * foo = [Foo alloc];
name1 = @“嗯”;
name2 = [富吧];// return a (NSString *)
[foo release];
}

-(void) b {
NSLog(@"%@", name1); // 它工作
NSLog(@"%@", name2); // 我得到一个 EXC_BAD_ACCESS...
}

为什么我有这个问题?我该如何解决?
谢谢 !

编辑:我刚刚解决了问题,我忘记了“保留”......

4

3 回答 3

1

您需要阅读Cocoa 内存管理指南

您在代码中所做的一些事情表明您没有掌握可可内存管理的基本概念。

例如:

[Foo alloc];

你没有初始化'foo'。alloc耦合和init调用在一起是常见的做法,例如:[[Foo alloc] init];这将确保对象成员和状态是您在创建后所期望的。

name2 = [foo bar]; // returns a (NSString *)

bar方法很可能返回一个autoreleased字符串。将其分配给 后您不会保留它name2,因此将在方法返回后的一段时间内将其释放。这就是您的代码崩溃的原因。您正在尝试访问已释放的对象。指向的对象name2被释放和释放,但指针没有设置为 nil,这意味着它指向的内存现在可以包含任何东西。它是未定义的。

之所以name1有效,是因为在 Cocoa 中使用文字 @"" 字符串需要特别考虑。当这样使用字符串时,它会变成“内部化”。如果您创建两个包含相同文本的文字字符串,系统将对其进行优化,使这两个字符串都指向内存中的一个对象。

也就是说,如果您的代码如下所示:

NSString *myString1 = @"hello";
NSString *myString2 = @"hello";

NSLog(@"string1: %p, string2: %p", myString1, myString2);

这将导致一条消息看起来像:string1: 0x123456, string2: 0x123456。这里要注意的重要一点是内存地址是相同的。字符串指向同一个对象,即使它们在代码中是不同的实例。

于 2010-04-18T00:15:31.987 回答
0

我昨天收到 EXC_BAD_ACCESS 错误。原来我正在调用release一个导致它被删除的对象,然后我尝试使用它。

你没有打电话release给任何你不应该做的事情,是吗?

只是一个友好的提醒:如果你不打电话allocretain在一个物体上,你不打电话release。使用您提供的代码,这似乎不是问题所在。但我想指出这一点以防万一。

于 2010-04-17T20:09:04.143 回答
0

乔尔是对的。尝试查看您的 [foo bar] 函数,可能在该函数中您正在释放任何对象

于 2010-04-17T20:12:43.077 回答