泄漏或崩溃 - 自动释放和释放之间的区别 [英] Leak or Crash - difference between autorelease and release

查看:82
本文介绍了泄漏或崩溃 - 自动释放和释放之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个理解问题.给出了这个方法:

I have a comprehension question. This method is given:

- (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;
}

如果我取消对 release 的注释,应用程序会崩溃并说它无法访问已发布的对象.
如果不releaseresult 字符串,仪器会报告泄漏(NSPlaceholderString).

If I uncomment the release the App would crash and say it cannot access a released object.
By not releaseing the result string Instruments would report a leak (NSPlaceholderString).

我可以在我 alloc 它的同一行 autorelease 它,这将解决问题(我目前正在我的应用程序中这样做).

I can autorelease it on the same line I alloc it, that would solve the problem (which I'm currently doing in my App).

如果我理解正确 stringByAppendingString: 应该创建一个自动释放的对象,以便可以释放旧"结果.然后方法 arrayWithObject: 应该 copy 对象到一个数组中.所以我的想法是将字符串复制到数组后释放.

If I understand it correctly stringByAppendingString: should create an autoreleased object so the 'old' result could be deallocated. Then the method arrayWithObject: should copy the object into an array. So my thought was to release the string after it was copied to the array.

我是否遗漏了什么或我的知识有什么问题?

Am I missing something or something wrong with my knowledge?

推荐答案

让我们逐行检查您的代码.

Let's go through your code line by line.

- (NSArray*)test {
 NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://stackoverflow.com/"]];

这将创建一个数据对象.您不拥有它,但它会在该方法的剩余时间里一直存在.到目前为止,一切都很好.

This creates a data object. You don't own it, but it will stick around for the rest of the method's time. So far, so good.

 NSString *result = [[NSString alloc] initWithBytes:[data bytes] 
                                             length:[data length] 
                                           encoding:NSMacOSRomanStringEncoding];

这将创建一个您拥有的字符串对象.同样,这里没问题 - 我们只需要稍后发布即可.

This creates a string object that you own. Again, no problem here — we just need to release it later.

result = [result stringByAppendingString:@"something"];

您丢弃了对 result 中的字符串对象的引用,并存储了一个不属于您的新字符串对象.这是一个泄漏,因为您不能再释放原始字符串.此外,您正确地注意到新字符串可以被视为自动释放的对象 - 这意味着您不应该释放它.

You throw away your reference to the string object that was in result and store a new string object that you do not own. This is a leak because you can no longer release the original string. Also, you're correct in noting that the new string can be treated as an autoreleased object — which means you should not release it.

NSArray *arr = [NSArray arrayWithObject:result];

与您的看法相反,这不会复制任何内容.它只是保留对新字符串的引用并保留它.

Contrary to your belief, this does not copy anything. It merely keeps a reference to the new string and retains it.

//[result release];

此时你不应该释放 result,因为它包含的对象不是你拥有的——你是从 stringByAppendingString: 得到的,而不是从带有 newallocretaincopy 的名称.释放这个你不拥有的对象几乎肯定会在某个时候导致崩溃.您拥有并应该释放的旧对象早在两行之前丢失了,而在其位置释放其他东西也无济于事.

You should not release result at this point, because the object it contains is not one you own — you got it from stringByAppendingString:, not from a method with new, alloc, retain or copy in its name. Releasing this object that you do not own will almost certainly result in a crash at some point. The old object that you own and should release was lost two lines earlier, and releasing something else in its place won't help.

这篇关于泄漏或崩溃 - 自动释放和释放之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆