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 - 内存泄漏和应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
iOS4 调用 ImageNamed:仍然泄漏或导致内存问题?