NSDocument - 内存泄漏&应用崩溃

时间:2011-09-30 20:21:32

标签: objective-c macos cocoa memory-leaks nsdocument

我的基于文档的应用中存在内存泄漏。它启动很好,我可以打开或创建一个新文档,但只有一两次,然后应用程序崩溃。 我在Xcode中使用了分析工具,没有任何问题。

然而,仪器显示内存泄漏,但我找不到它在我的代码中的位置 使用Objects Allocations,我可以看到当我关闭文档时我的NSDocument子类没有被释放......我真的不知道这是否是预期的行为。

以下是我阅读和撰写文档的方式:

-(NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
    NSMutableData *d = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
                                 initForWritingWithMutableData:d];
    [archiver encodeObject:[self machine]
                    forKey:IVPCodingKeyMachine];
    [archiver finishEncoding];
    [archiver release];
    if(outError) {
        *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
                                        code:unimpErr
                                    userInfo:NULL];
    }
    return d;
}

-(BOOL)readFromData:(NSData *)data
             ofType:(NSString *)typeName
              error:(NSError **)outErro {
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
                                     initForReadingWithData:data];
    machine = [[unarchiver decodeObjectForKey:IVPCodingKeyMachine] retain];
    [machine setDelegate:self];
    [unarchiver finishDecoding];
    [unarchiver release];
    if(outError) {
        *outError = [NSError errorWithDomain:NSOSStatusErrorDomain
                                        code:unimpErr
                                    userInfo:NULL];
    }
    return YES;
}

machine属性的声明如下:@property(readonly) IVPMachine *machine; ivar上的machineIVPMachine类符合NSCoding协议。如果是新文档,我已经覆盖了-(id)initWithType:(NSString *)typeName error:(NSError **)outError;方法,这里是我使用的代码:

-(id)initWithType:(NSString *)typeName error:(NSError **)outError {
    self = [super initWithType:typeName error:outError];
    if (self) {
        machine = [[IVPMachine alloc] initWithCreditAmount:2000];
        [machine setDelegate:self];
        [machine setGame:[[IVPGamesLibrary sharedInstance]
                           objectInGamesAtIndex:0]];
    }
    return self;
}

最后,在-(void)dealloc;方法中,我发布了machine ivar。

我无法弄清楚bug的位置..当我在我的应用程序中关闭文档时,是不是应该释放我的文档子类实例?

欢迎任何帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

作为一个疯狂的猜测,您是否实施了-[IVPMachine setDelegate:]来保留代表?如果是这样,请不要这样做。代表们应该是弱参考,即不保留。你拥有IVPMachine,所以如果它拥有你的权利,那就是循环所有权,这就是保持文件和IVPMachine活着的原因。

更实际的是,在仪器中挖掘更多。它不仅可以告诉您泄漏的东西,还可以告诉您发生的每一次保留和释放。查看该列表以查找未平衡的保留。