2011-06-03 81 views
0

在测试一些代码时,我遇到了一个问题。听到是我的代码和日志。NSString释放问题

(IBAction) DynamicBtnClicked:(id)sender 
{ 
NSString *strLog = [[NSString alloc] initWithString:@"SubView Index is..."]; 
NSLog(@"initialized strLog address is = %p, retainCount = %d", strLog, [strLog retainCount]); 
if ([self.view.subviews count] > 0) { 
    for (int i = 0 ; i < [self.view.subviews count] ; i++) { 
     UIView *tmpView = [self.view.subviews objectAtIndex:i]; 
     strLog = [strLog stringByAppendingFormat:@"%d view`s index = %d, tag = %d", i, i,[tmpView tag]]; 
     NSLog(@"appended strLog address is = %p, retainCount = %d", strLog, [strLog retainCount]); 
    } 
} 

NSLog(@"after appended strLog address is = %p, retainCount = %d", strLog, [strLog retainCount]);  
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:strLog delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 
[alert show]; 
[alert release]; 

NSLog(@"after using strLog address is = %p, retainCount = %d", strLog, [strLog retainCount]); 
[strLog release]; 
} 

及以下登录

2011-06-03 14:36:11.038 MakeViewUsingCode[3918:40b] initialized strLog address is = 0x45c4, retainCount = 2147483647 
2011-06-03 14:36:11.039 MakeViewUsingCode[3918:40b] appended strLog address is = 0x9c028d0, retainCount = 1 
2011-06-03 14:36:11.040 MakeViewUsingCode[3918:40b] appended strLog address is = 0x9c021b0, retainCount = 1 
2011-06-03 14:36:11.041 MakeViewUsingCode[3918:40b] after appended strLog address is = 0x9c021b0, retainCount = 1 
2011-06-03 14:36:11.081 MakeViewUsingCode[3918:40b] after using strLog address is = 0x9c021b0, retainCount = 3 
2011-06-03 14:36:11.087 MakeViewUsingCode[3918:40b] *** -[CFString release]: message sent to deallocated instance 0x9c021b0 
dlopen(/Developer/Library/Xcode/PrivatePlugIns/DebuggerFoundation.ideplugin/Contents/Resources/DebuggerIntrospectionSupport.dylib, 0x0000000A) 
dyld: loaded: /Developer/Library/Xcode/PrivatePlugIns/DebuggerFoundation.ideplugin/Contents/Resources/DebuggerIntrospectionSupport.dylib 
Current language: auto; currently objective-c 

我所知,目前在我的代码中的内存泄漏,但不是一个真正的问题。(这是故意的。)

真正的问题是当我运行我的代码时,发生EXC_BAD_ACCESS运行时错误。

在我的代码中,我向接收者发送消息一次,但日志显示我错误的原因是NSString对象的实例已被释放!

如果我发送消息给接收者发布两次,第一个位置在哪里?

谁能告诉我它在哪里?

谢谢。

回答

0

当您在循环中首次将该新字符串分配给strlog时,您将失去对第一个字符串的引用。

NSString *strLog = [[NSString alloc] initWithString:@"SubView Index is..."]; 
for (int i = 0 ; i < [self.view.subviews count] ; i++) { 
    // since you're not releasing the current reference, it's replaced with 
    // the following reference and thus leaked 
    strLog = [strLog stringByAppendingFormat:@"%d view`s index = %d, tag = %d", i, i,[tmpView tag]]; 
} 

相信是stringByAppendingFormat返回一个自动释放的NSString。如果是这种情况,我怀疑你所看到的错误是因为,你发布了两次strLog的最后一个引用(当对象被创建时的隐式自动释放和方法结束时的显式释放)。

+0

谢谢,jok! :D – leechoohyoung 2011-06-03 06:48:16

0

不要依赖retainCount多。他们可能会误导人。只要坚持内存管理规则,你会做得很好。这里的问题是这条线,

strLog = [strLog stringByAppendingFormat:@"%d view`s index = %d, tag = %d", i, i,[tmpView tag]]; 

你这样做,strLog点后到自动释放的字符串。您尚未声明此字符串的所有权,但仍然在方法结束时释放它。所以想象它被创造一次并且释放两次。那是你的问题。如果您只想将字符串附加到您创建的实例,则必须使用NSMutableString

+0

非常感谢!是的,我应该考虑所有权!再次感谢! – leechoohyoung 2011-06-03 06:47:37