【问题标题】:Handling memory leaks in factory methods处理工厂方法中的内存泄漏
【发布时间】:2011-09-16 08:19:34
【问题描述】:

我正在开发一个客观的 C 框架,最终将作为静态库发布。但是,当我在泄漏工具中将该库集成到实际应用程序(通过添加静态库)时,我发现存在一些内存泄漏。

这是一个示例场景。

@implementation Test

@synthesize testNumber

+(Test) createTestInstance {

    Test *test = [[Test alloc] init];
    test.testNumber = [[NSDecimerNumber alloc] initWithInt:1];

    return test;
}

-(void) dealloc {
    [testNumber release];
}

@end

虽然我在 dealloc 中释放了 testNumber 变量,但我在 Leaks 工具中的 alloc 位置看到了内存泄漏。这可能是什么问题?

由于这是一个供用户调用的库,从库代码中释放这些变量是否是最佳实践?

谢谢

【问题讨论】:

  • 这是单身人士吧?它缺少一些东西。在 stackoverflow 上是一个用最好的单例回答的问题。稍微搜索一下!
  • 我在问题或代码中看不到任何表明单例的内容。
  • 这不是单例。我知道有很多问题。最好的方法是使其成为实例变量。只是想检查这种情况下的内存行为。

标签: iphone objective-c cocoa memory-leaks retaincount


【解决方案1】:

我在这里看到两个问题。如果testNumber 是一个保留属性,那么您使用以下语句过度保留它:

test.testNumber = [[NSDecimerNumber alloc] initWithInt:1];

alloc-init 和属性访问器都保留了该对象。因此,应该是:

test.testNumber = [[[NSDecimerNumber alloc] initWithInt:1] autorelease];

不用说你还需要在dealloc方法中释放testNumber

另外,我知道createTestInstance 是创建Testobjects 的便捷构造函数,它应该根据Object Ownership Policy 返回一个自动释放的对象(仅限名称以“alloc”、“new”、“ copy”或“mutableCopy”返回一个你拥有的对象):

+ (id)createTestInstance {

    Test *test = [[[self alloc] init] autorelease];
    test.testNumber = [[[NSDecimerNumber alloc] initWithInt:1] autorelease];

    return test;
}

最后,正如@Josh Caswell 所建议的,便利构造函数应该返回id 而不是特定的类。来自The Objective-C Programming Language

方便的返回类型 构造函数是 id 出于同样的原因 它是初始化方法的 id,如 在“Constraints and Conventions”中讨论。

此外,他们应该使用self 而不是硬编码的类名来分配初始化实例,以便正确处理子类化(这里self 指的是类对象本身,因为这是一个类方法)。

【讨论】:

  • +1 你打败了我。理想情况下,您也不会将 create 添加到方法名称中,因为它在内存管理方面发送不同的消息。
  • 这意味着对于 init 和 alloc 是否将保留计数增加 2?
  • 使用[NSDecimalNumber numberWithInt: 1]创建分配给test.testNumber的对象
  • @Deepak - 您指的是“创建规则”,但这是 Cocoa,而不是 Carbon。对于内存管理,“创建”一词在这里没有特殊含义。
  • 构造方法应该返回id,并使用self而不是硬编码的类名,否则子类化会很痛苦。考虑如果+[NSArray array]+ (NSArray *) array { return [[[NSArray alloc] init] autorelease]; }NSMutableArray 会发生什么(您还缺少返回值中的星号:(Test) 应该是(Test *))。
猜你喜欢
  • 2015-11-12
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 2015-06-14
  • 1970-01-01
  • 2020-02-29
  • 2017-08-11
  • 1970-01-01
相关资源
最近更新 更多