在测试一些代码时,我遇到了一个问题。听到我的代码和日志。
(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];
}
以下是Log
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运行时错误。
在我的代码中,我向接收者发送一条消息以释放一次但是Log向我显示错误的原因是NSString对象的实例已经被释放!
如果我向接收者发送信息两次发布,第一个位置在哪里?
谁能告诉我它在哪里?
感谢。
答案 0 :(得分: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的最后一次引用(创建对象时的隐式自动释放以及方法结束时的显式释放)。 p>
答案 1 :(得分:0)
不要太依赖retainCount
。它们可能会产生误导。坚持内存管理规则,你会做得很好。这里的问题是这一行,
strLog = [strLog stringByAppendingFormat:@"%d view`s index = %d, tag = %d", i, i,[tmpView tag]];
执行此操作后,strLog
指向自动释放的字符串。您尚未声明此字符串的所有权,但仍然在方法结束时将其释放。所以想象它被创造一次并发布两次。那是你的问题。如果您只想将字符串附加到您创建的实例,则必须使用NSMutableString
。