2 release objective-c autorelease nsstring nsdata
我有一个理解问题.给出了这种方法:
- (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;
}
Run Code Online (Sandbox Code Playgroud)
如果我取消注释,releaseApp会崩溃并说它无法访问已发布的对象.
不release通过result字符串仪器会报告泄漏(NSPlaceholderString).
我可以autorelease在同一条线上alloc,它可以解决问题(我正在我的应用程序中进行).
如果我理解正确stringByAppendingString:应该创建一个自动释放的对象,以便可以释放"旧"结果.然后该方法arrayWithObject:应该copy将对象放入数组中.所以我的想法是在将字符串复制到数组后释放它.
我错过了我的知识吗?
Chu*_*uck 11
让我们逐行完成您的代码.
- (NSArray*)test {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://stackoverflow.com/"]];
Run Code Online (Sandbox Code Playgroud)
这将创建一个数据对象.你不拥有它,但它会在方法的剩余时间内保持不变.到现在为止还挺好.
NSString *result = [[NSString alloc] initWithBytes:[data bytes]
length:[data length]
encoding:NSMacOSRomanStringEncoding];
Run Code Online (Sandbox Code Playgroud)
这将创建您拥有的字符串对象.再次,这里没问题 - 我们只需要稍后发布它.
result = [result stringByAppendingString:@"something"];
Run Code Online (Sandbox Code Playgroud)
您丢弃对其中的字符串对象的引用,result并存储您不拥有的新字符串对象.这是泄漏,因为您无法再释放原始字符串.另外,你注意到新字符串可以被视为自动释放的对象是正确的 - 这意味着你不应该释放它.
NSArray *arr = [NSArray arrayWithObject:result];
Run Code Online (Sandbox Code Playgroud)
与您的信念相反,这不会复制任何内容.它只保留对新字符串的引用并保留它.
//[result release];
Run Code Online (Sandbox Code Playgroud)
你不应该释放result在这一点上,因为它包含的对象不是一个你自己-你得到它stringByAppendingString:,而不是从法new,alloc,retain或copy在其名称.释放您不拥有的此对象几乎肯定会在某些时候导致崩溃.您拥有并且应该发布的旧对象早先丢失了两行,并且在其位置释放其他内容将无济于事.
result = [result stringByAppendingString:@"something"];
Run Code Online (Sandbox Code Playgroud)
此行用新的自动释放字符串替换第一个分配的字符串.
所以第一个字符串泄露,第二个字符串不应该被释放.这解释了为什么取消注释释放线崩溃.
| 归档时间: |
|
| 查看次数: |
1488 次 |
| 最近记录: |