NSString释放问题

发布于 2024-11-13 07:17:47 字数 2340 浏览 2 评论 0原文

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

(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 对象的实例已经被释放!

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

谁能告诉我它在哪里?

谢谢。

While testing some code, I meet a problem. Hear is my code and Log.

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

and below is 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

I know, there is a memory leak in my code but that is not a real problem.(it was on purpose.)

Real problem is, when I run my code, EXC_BAD_ACCESS runtime error occurs.

In my code, I send a message to receiver to release once but the Log shows me the reason for error is that the instance of NSString object is already deallocated!

If I send a message to receiver to release twice, where is first position?

Can anyone tell me where it is?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凹づ凸ル 2024-11-20 07:17:47

不要过度依赖 retainCount。它们可能会产生误导。只要遵守内存管理规则就可以了。这里的问题是这一行,

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

执行此操作后,strLog 指向一个自动释放的字符串。您尚未声明对此字符串的所有权,但您仍然在方法结束时释放了它。因此想象一下它被创建一次并发布两次。那是你的问题。如果您只想将字符串附加到您创建的实例中,则必须使用 NSMutableString

Do not rely on retainCount much. They can be misleading. Just stick to memory management rules and you will do just fine. The problem here is this line,

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

After you do this, strLog points to an autoreleased string. You haven't claimed ownership on this string but still you release it at the end of the method. So imagine it being created once and released twice. That's your problem. If you just want to append the string to the instance you've created, you will have to use an NSMutableString.

凉城已无爱 2024-11-20 07:17:47

当您在循环中第一次将该新字符串分配给 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 的最后一个引用(创建对象时的隐式自动释放和方法结束时的显式释放)。

When you assign that new string to strlog the first time in the loop, you're losing the reference to the first string.

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

I believe that stringByAppendingFormat returns an autoreleased NSString. If this is the case, I suspect the error you're seeing is because, you're releasing the last reference to strLog twice (the implicit autorelease when the object is created and the explicit release at the end of the method).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文