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

Dil*_*han 3 iphone cocoa memory-leaks objective-c 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
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

alb*_*amg 11

我在这看到两个问题.如果testNumber是保留属性,则使用此语句对其进行过度保留:

test.testNumber = [[NSDecimerNumber alloc] initWithInt:1];
Run Code Online (Sandbox Code Playgroud)

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

test.testNumber = [[[NSDecimerNumber alloc] initWithInt:1] autorelease];
Run Code Online (Sandbox Code Playgroud)

没有必要提到您仍需要testNumberdealloc方法中发布.

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

+ (id)createTestInstance {

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

    return test;
}
Run Code Online (Sandbox Code Playgroud)

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

方便构造函数的返回类型是id,原因与初始化方法的id相同,如" 约束和约定"中所述.

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

  • +1你打败了我.理想情况下,您也不会在方法名称中添加"create",因为它在内存管理方面发送了不同的消息. (3认同)
  • 构造方法应该返回`id`,并使用`self`而不是硬编码的类名,或者子类化将是一种痛苦.如果`+ [NSArray array]`是`+(NSArray*)array {return [[[NSArray alloc] init] autorelease],请考虑`NSMutableArray`会发生什么?``(你也错过了返回值中的星号:`(Test)`应该是`(Test*)`). (2认同)