3

我正在开发一个目标 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 位置看到了内存泄漏。这里可能是什么问题?

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

谢谢你

4

1 回答 1

11

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

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

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

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

不用说你还需要testNumberdealloc方法中释放。

另外,我理解createTestInstance是创建Test对象的便利构造函数,它应该根据对象所有权策略返回一个自动释放的对象(只有名称以“alloc”、“new”、“copy”或“mutableCopy”开头的方法才会返回一个您拥有的对象):

+ (id)createTestInstance {

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

    return test;
}

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

便利构造函数的返回类型是 id,原因与初始化方法的 id 相同,如“<a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/ Chapters/ocAllocInit.html#//apple_ref/doc/uid/TP30001163-CH22-SW14" rel="nofollow">约束和约定。”</p>

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

于 2011-06-16T12:43:43.430 回答