NSDocument - 内存泄漏和应用程序崩溃

Posted

技术标签:

【中文标题】NSDocument - 内存泄漏和应用程序崩溃【英文标题】:NSDocument - memory leak & app crash 【发布时间】:2011-09-30 20:21:31 【问题描述】:

我的基于文档的应用程序出现内存泄漏。它启动正常,我可以打开或制作新文档,但只有一两次,然后应用程序崩溃。 我在 Xcode 中使用了分析工具,没有问题。

但是,Instruments 揭示了内存泄漏,但我找不到它在我的代码中的位置。 使用对象分配,当我关闭文档时,我可以看到我的 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; 上的 machine ivar 和 IVPMachine 类符合 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。

我不知道错误出在哪里。当我关闭应用程序中的文档时,我的文档子类实例不应该被释放吗?

欢迎任何帮助。谢谢。

【问题讨论】:

您从 I/O 方法返回的错误是错误的。您显然已经实现了它们,因此返回 unimpErr 是没有意义的。你应该返回一些更接近真相的东西; FoundationErrors.h 是一个不错的起点(请注意,这些错误位于 NSCocoaErrorDomain 中)。 【参考方案1】:

作为一个疯狂的猜测,你是否实现了-[IVPMachine setDelegate:] 来保留委托?如果是这样,请不要这样做。代表应该是弱引用,即非保留。您拥有 IVPMachine,因此如果它归还您,这就是循环所有权,并且是保持文档和 IVPMachine 存活的原因。

更实际的是,在 Instruments 中挖掘更多内容。它不仅可以告诉您您泄露了某些内容,还可以告诉您发生的每一次保留和释放。查看该列表以找到未平衡的保留。

【讨论】:

你猜的不错,IVPMachine 的委托确实被保留了。将属性定义更改为分配后,我不再遇到崩溃行为,并且发布了文档内容。有些东西仍然很奇怪:我仍然可以在 Instruments 中看到一些内存泄漏,但在底部的表格中没有任何条目。但是,没错,我必须更深入地研究该工具。谢谢。

以上是关于NSDocument - 内存泄漏和应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

媒体基础多个视频播放导致内存泄漏和未定义时间范围后崩溃

iOS 内存泄漏导致更改视图控制器崩溃

iOS4 调用 ImageNamed:仍然泄漏或导致内存问题?

iPhone 应用程序由于内存不足而崩溃,但在模拟器中运行良好

内存泄漏 - 应用程序以信号 9 退出

使用 NSMutableArray 时内存泄漏