泄漏报告看似无关的问题

时间:2010-04-20 19:13:32

标签: objective-c cocoa memory-leaks

我是Cocoa和Objective-C的新手。目前我正在开发一个相当基本的应用程序来测试我的知识,并将我正在阅读的一些内容付诸实践。一切正常,但Leaks报告了一些问题。

这些泄漏似乎都没有直接适用于我编写的代码(我已阅读并尝试遵循Apple关于内存分配的规则)。目前我的项目使用垃圾收集,我正在开发Snow Leopard。运行AnalysisTool发现我的代码没有问题(除了一些命名约定警告)。

目前我的应用程序使用了我连接到NSArrayController的NSTableView。与NSTableView交互似乎会导致泄漏报告问题(排序表列和其他标准用户交互等操​​作)。这让我相信我对NSArrayController(以及我对其内容源的实现)的使用是罪魁祸首。

目前,NSArrayController从我的应用程序委托中处理的NSMutableArray(计时器)接收其内容,如下所示:

- (id) init
{
    if (self = [super init])
    {
        timers = [NSMutableArray array];    
    }
    return self;
}
- (void) dealloc
{
    [timers release];
    [super dealloc];
}

在Interface Builder中,我的NSArrayController将其对象控制器设置为Timing类,定义如下:

@interface Timing : NSObject {
    NSString *desc;
    NSDate *timestamp;
    bool active;
}
@end

@implementation Timing
-(id) init
{
    if (self = [super init])
    {
        desc = @"New timing";
        timestamp = [[NSDate alloc] init];
        active = false;
    }
    return self;
}
-(void) dealloc
{
    [timestamp release];
    [super dealloc];
}
@end

我使用标准的Cocoa绑定来连接Add和Remove按钮来操作TableView,这些似乎工作正常(例如,单击Add会在TableView中创建一个值为'New timing'的行)。

Leaks报告称负责的图书馆是AppKit和CoreGraphics。虽然,老实说,我还是Leaks工具的新手 - 所以我可能会错误地读取它的输出。如果有帮助,我会放置其输出here的屏幕截图。如果有人能指出我正确的方向,那将非常感激。

顺便说一句,我也在尝试手动将对象添加到timers数组而不使用Cocoa绑定。这就是我想出的:

Timing *timingInstance = [[Timing alloc] init];
[timers addObject:timingInstance];
[timingInstance release];

[timersController setContent:timers];
[timersTableView reloadData];

同样,这似乎有效,但我认为最好问专家!

3 个答案:

答案 0 :(得分:2)

timers数组的内存管理不是完全正确。使用array工厂方法将返回已经自动释放的NSMutableArray实例,因此该对象的生命周期(可能)仅限于当前运行循环的结束,并且它将结束 - 在dealloc方法中调用release时发布。正确的方法如下:

- (id) init
{
    if (self = [super init])
    {
        timers = [[NSMutableArray alloc] initWithCapacity:0];
    }
    return self;
}

此方法将为您提供一个NSMutableArray实例,其保留计数为1,当您在dealloc方法中调用release时,该实例将降至零(并正确释放内存)。通过alloc方法中init的调用,可以平衡release方法中对dealloc的调用。我注意到这是您在NSDate课程中用于Timing对象的确切模式,因此您已经熟悉了这个想法。

答案 1 :(得分:2)

您写的代码没有泄露。在leaks下运行时,Cocoa框架有时会生成错误的泄漏报告,因为在框架实现中使用的单例和缓存等有时会显示为泄漏,即使它们不是。

最好运行ObjectAlloc和/或ObjectGraph工具,以了解对象何时被分配和释放。

答案 2 :(得分:1)

  

目前我的项目正在使用   垃圾收集和我正在发展   在雪豹上

我不明白。你正在使用垃圾收集吗?如果是这样,那么GC负责为你释放物品,所以你在任何地方使用“释放”都绝对没有。启用GC后,将忽略释放调用。您只在自己管理内存时才使用发行版,即GC关闭时。此外,你的dealloc方法也没有做任何事情。在GC中,从未使用过该方法。当你创建一个对象,然后你完成它,你告诉GC,通过将它设置为零来摆脱对象是可以的。这就是你要做的一切。不需要“释放”或需要dealloc方法。根据需要将事情设置为零或不。