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

发布于 2024-11-15 18:05:40 字数 513 浏览 3 评论 0 原文

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

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

谢谢

I am developing an objective C framework which will ship as a static library at the end. But when I integrate that library to an actual application (by adding the static library) in the leaks tools I see some memory leaks present.

Here is an example scenario.

@implementation Test

@synthesize testNumber

+(Test) createTestInstance {

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

    return test;
}

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

@end

Although I release testNumber variable in dealloc I see a memory leak in Leaks tool at alloc position. What can be the issue here?

Also as this is a library provided for user to invoke, is it a best practice to release those variable from the library code?

Thank You

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

于我来说 2024-11-22 18:05:40

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

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

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

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

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

另外,我知道 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,如
在“约束和约定。”

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

I see two problems here. If testNumber is a retain property, you are overretaining it with this statement:

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

Both alloc-init and the property accessor are retaining the object. Therefore, it should be:

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

There is no need to mention that you still need to release testNumber in the dealloc method.

Also, I understand createTestInstance is a convenience constructor to create Testobjects and it should return an autoreleased object according to the Object Ownership Policy (only methods with names that start with “alloc”, “new”, “copy”, or “mutableCopy” return an object you own):

+ (id)createTestInstance {

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

    return test;
}

Finally, as suggested by @Josh Caswell, convenience constructors should return id instead of the specific class. From The Objective-C Programming Language:

The return type of convenience
constructors is id for the same reason
it is id for initializer methods, as
discussed in “Constraints and Conventions.”

Also, they should use self instead of the hard-coded class name to alloc-init the instance in order to handle subclassing properly (self here refers to the class object itself since this is a class method).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文