泄漏或崩溃 - 自动释放和释放之间的区别 [英] Leak or Crash - difference between autorelease and release
问题描述
我有一个理解问题.给出了这个方法:
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
的注释,应用程序会崩溃并说它无法访问已发布的对象.
如果不release
result
字符串,仪器会报告泄漏(NSPlaceholderString).
If I uncomment the release
the App would crash and say it cannot access a released object.
By not release
ing 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:
得到的,而不是从带有 new
、alloc
、retain
或 copy
的名称.释放这个你不拥有的对象几乎肯定会在某个时候导致崩溃.您拥有并应该释放的旧对象早在两行之前丢失了,而在其位置释放其他东西也无济于事.
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屋!