我正在开发一个目标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工具中的内存泄漏。这可能是什么问题?
此外,由于这是一个供用户调用的库,从库代码中释放这些变量是最佳做法吗?
谢谢
答案 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对象本身,因为这是一个类方法)。