处理工厂方法中的内存泄漏

时间:2011-06-16 12:38:12

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

我正在开发一个目标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变量,但我在alloc位置看到Leaks工具中的内存泄漏。这可能是什么问题?

此外,由于这是一个供用户调用的库,从库代码中释放这些变量是最佳做法吗?

谢谢

1 个答案:

答案 0 :(得分:11)

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

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

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

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

无需提及您仍需要在testNumber方法中发布dealloc

另外,我理解createTestInstance是创建Test对象的便利构造函数,它应该根据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而不是硬编码的类名来分配init实例,以便正确处理子类化self这里指的是class对象本身,因为这是一个类方法)。