Instruments 说我泄漏了一根弦,但我找不到它

发布于 2024-12-05 22:34:04 字数 1096 浏览 0 评论 0原文

我使用Instruments中的leaks工具来测试代码,但是leaks工具似乎无法找到泄漏。

在我的代码末尾, NSLog(@"str count:%d",[str keepCount]); 的输出是 3。为什么?我不会覆盖dealloc。 [a.name keepCount] 是否只有一次 我只自动释放 str 一次。所以 str 不应该泄漏。

@interface DataMode : NSObject {

    NSString * name;
}

@property (retain) NSString * name;

- initWithName:(NSString * )name_;
@end


@implementation DataMode

@synthesize name;

- initWithName:(NSString * )name_
{
    if ([super init] != nil)
    {
        name = name_;
        return self;
    }
    return nil;
}

@end


- (void) pressed:(id)sender
{
    for( int i = 0;i<10000000;i++)
    {
        NSString * str = [NSString stringWithFormat:@"zhang"];
        DataMode * a = [[DataMode alloc] initWithName:str];
        NSLog(@"a0 count:%d",[a retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"a1 count:%d",[a retainCount]);
        [ a  release];
        NSLog(@"str count:%d",[str retainCount]);
        NSLog(@"str count:%d",[str retainCount]);
    }


}
@end

I used the leaks tool in Instruments to test the code, but the leaks tool cannot seem to find the leak.

At the end of my code, the output of NSLog(@"str count:%d",[str retainCount]); is 3. Why? I don't override the dealloc. [a.name retainCount] is there just one time
and I only autorelease str for one time. So str shouldn't leak.

@interface DataMode : NSObject {

    NSString * name;
}

@property (retain) NSString * name;

- initWithName:(NSString * )name_;
@end


@implementation DataMode

@synthesize name;

- initWithName:(NSString * )name_
{
    if ([super init] != nil)
    {
        name = name_;
        return self;
    }
    return nil;
}

@end


- (void) pressed:(id)sender
{
    for( int i = 0;i<10000000;i++)
    {
        NSString * str = [NSString stringWithFormat:@"zhang"];
        DataMode * a = [[DataMode alloc] initWithName:str];
        NSLog(@"a0 count:%d",[a retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"name1 count:%d",[a.name retainCount]);
        NSLog(@"a1 count:%d",[a retainCount]);
        [ a  release];
        NSLog(@"str count:%d",[str retainCount]);
        NSLog(@"str count:%d",[str retainCount]);
    }


}
@end

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

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

发布评论

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

评论(3

笑饮青盏花 2024-12-12 22:34:04

保留计数没有用。别叫它。

它对于查找泄漏没有什么用处,因为有更好、更准确、误导性更少的工具可用。

您的代码存在几个问题(但泄漏不是其中之一):

  • NSString* 属性应该是 copy

  • 您不使用该属性在 init 中设置字符串值,因此 DataMode 实例不会保留其字符串。

  • 没有 dealloc 方法

至于保留计数;我很惊讶它是“3”。我希望它是 2bazillionsomething,因为这是一个常量字符串(常量字符串的 stringWithString: 只是返回字符串)。因为您使用了 stringWithFormat:,常量字符串转为非常量字符串。如果您使用了常量字符串或stringWithString:,那么它将是无数的东西(无符号-1...UINT_MAX...)。

无论如何,您有:

  • +1 用于 stringWithString:
  • +1 用于调用 a.name
  • +1 用于调用 a.name

+3 总体。

如果 Instruments 声称存在泄漏,请发布屏幕截图。

retainCount is useless. Don't call it.

It is not useful for finding leaks as there are much better, more accurate, and less misleading tools available.

There are several problems with your code (but leaking isn't one of them):

  • NSString* properties should be copy

  • you don't use the property to set the string value in init, thus the DataMode instances are not retaining their strings.

  • there is no dealloc method

As for the retain counts; I'm surprised it is "3". I'd expect it to be 2bazillionsomething as that is a constant string (and stringWithString: of a constant string just returns the string).Since you used stringWithFormat:, the constant string is turned into a non-constant string. If you had used the constant string or stringWithString:, it'd be abazillionsomething (unsigned -1... UINT_MAX...).

In any case, you have:

  • +1 for stringWithString:
  • +1 for calling a.name
  • +1 for calling a.name

+3 overall.

If Instruments is claiming a leak, post a screenshot.

2024-12-12 22:34:04

我引用 NSObject 协议参考 对于 -retainCount

此方法通常对于调试内存管理问题没有任何价值。因为任意数量的框架对象可能保留了一个对象以保存对其的引用,而同时自动释放池可能在对象上保存任意数量的延迟释放,因此您不太可能从中获得有用的信息方法。

由于多种原因,保留计数可能为 3;如果您无法使用泄漏工具找到泄漏,则很可能没有泄漏。不必担心保留计数的实际值。

如果您真的对为什么是 3 感兴趣,请记住:

  • 来自 DataMode 对象 a 的引用可能会一直保留,直到最近的自动释放池耗尽为止
  • 您仍然在 str 变量中保存一个引用
  • NSString 类簇,除其他外,做了一些 - 异常难以解释的 - 在内部缓存东西,所以你可能会在这里或那里看到一些没人能解释的保留

I quote the NSObject protocol reference for -retainCount:

This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.

The retain count could be 3 for any number of reasons; if you can't find a leak with the leaks tool, it's likely you don't have a leak. Don't worry about the actual value of the retain count.

If you're really interested in why it's 3, recall that:

  • The reference from your DataMode object a will likely be held until the closest autorelease pool is drained
  • You're still holding a reference in the str variable
  • The NSString class cluster, among others, does some - unusually inexplicable - caching things internally, so you may see a few retains here and there for which nobody can account
妳是的陽光 2024-12-12 22:34:04

由于您使用便捷方法来创建自动释放的 str ,因此您将不会看到以这种方式使用保留计数的确定行为。

检查我对另一个问题的回答,并将这些方法添加到 DataMode 中,您应该会看到框架何时从自动释放池中释放您的对象。

在类中覆盖release和retain

Since you are using the convenience method to create str which is autoreleased you will not see determinate behavior using retain counts in this way.

Check my response to another question and add those methods to DataMode and you should see when the framework releases your objects from the autorelease pool.

Overriding release and retain in your class

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