Objective c 泄漏或崩溃-自动释放和释放之间的差异

Objective c 泄漏或崩溃-自动释放和释放之间的差异,objective-c,nsstring,release,nsdata,autorelease,Objective C,Nsstring,Release,Nsdata,Autorelease,我有一个理解问题。该方法如下所示: - (NSArray*)test { NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://stackoverflow.com/"]]; NSString *result = [[NSString alloc] initWithBytes:[data bytes] length:[data length] e

我有一个理解问题。该方法如下所示:

- (NSArray*)test {
 NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://stackoverflow.com/"]];
 NSString *result = [[NSString alloc] initWithBytes:[data bytes] 
            length:[data length] 
             encoding:NSMacOSRomanStringEncoding];
 result = [result stringByAppendingString:@"something"];
 NSArray *arr = [NSArray arrayWithObject:result];
 //[result release];
 return arr;
}
如果我取消注释
发布
,应用程序将崩溃,并说它无法访问已发布的对象。
通过不
释放
ing
结果
string仪器将报告泄漏(NSPlaceholderString)

我可以
autorelease
I
alloc
it在同一行上,这将解决问题(我目前正在我的应用程序中)

如果我正确理解了
stringByAppendingString:
应该创建一个自动释放的对象,这样就可以释放“旧”结果。然后,方法
arrayWithObject:
应该
将对象复制到数组中。所以我的想法是在将字符串复制到数组后释放它

我的知识是否有遗漏或错误

result = [result stringByAppendingString:@"something"];
此行用新的自动释放字符串替换第一个分配的字符串


因此,第一个字符串泄漏,第二个字符串不应释放。这解释了为什么取消注释发布行会崩溃。

让我们逐行检查代码

- (NSArray*)test {
 NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://stackoverflow.com/"]];
这将创建一个数据对象。您不拥有它,但它将在方法的剩余时间内一直存在。到目前为止,一切顺利

 NSString *result = [[NSString alloc] initWithBytes:[data bytes] 
                                             length:[data length] 
                                           encoding:NSMacOSRomanStringEncoding];
这将创建您自己的字符串对象。同样,这里没有问题-我们只需要稍后发布它

result = [result stringByAppendingString:@"something"];
您放弃了对
result
中字符串对象的引用,并存储了一个您不拥有的新字符串对象。这是一个泄漏,因为您无法再释放原始字符串。另外,您注意到新字符串可以被视为自动释放对象是正确的,这意味着您不应该释放它

NSArray *arr = [NSArray arrayWithObject:result];
与你的想法相反,这并没有复制任何东西。它只保留对新字符串的引用并保留它

//[result release];

此时不应释放
result
,因为它包含的对象不是您自己的-您是从
stringByAppendingString:
获得它的,而不是从名为
new
alloc
retain
copy
的方法获得的。释放这个您不拥有的对象几乎肯定会在某个时候导致崩溃。您拥有并应释放的旧对象在两行之前丢失,而在其位置释放其他对象也无济于事。

这是正确的。你可以通过
autorelease
ing将初始赋值改为
result
@Seamus来解决这个问题。我从来没有问过如何解决这个问题,我想要一个解释。我已经在我的问题中写了如何修复它,所以阅读整个问题,不仅仅是示例代码是有帮助的。