我创建了一个名为“DateTracker”的对象,它符合 NSCoding,因此它包含 encodeWithCoder 和 initWithCoder 方法。当我初始化它时,我调用以下内容:
DateTracker *currentTracker = [[DateTracker alloc] initFromFile];
initFromFile 方法如下所示:
- (id)initFromFile {
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] attributesOfFileSystemForPath:filePath error:NULL]) {
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
self = [unarchiver decodeObjectForKey:kDateDataKey];
[unarchiver finishDecoding];
[unarchiver release];
[data release];
}
return self;
}
但是当我尝试调用
[currentTracker release];
我的应用崩溃了。
当我使用性能工具运行应用程序来检查内存泄漏时,它会提示我没有释放这个对象。
知道我做错了什么吗?
最佳答案
这一行:
self = [unarchiver decodeObjectForKey:kDateDataKey];
会给你带来麻烦。
您正在做的是分配一个 DateTracker 对象 ([DateTracker alloc]
),然后创建一个新的 DateTracker 对象(通过 -decodeObjectForKey:
)并使“self”指针指向新对象。这有两个问题:
- 你不再有对旧对象的引用,所以它被泄露了
- 新对象没有被保留,所以它消失了(或者如果你试图释放它会导致崩溃)
我想说让对象替换自身的方法有点可疑。也许您最好将 filePath
变量移到 DateTracker
对象之外,并通过类似以下方式取消存档:
DateTracker *currentTracker = [[DateTracker unarchiveFromFile:filePath] retain];
其中 unarchiveFromFile:
是一个类方法,它本质上完成了 initFromFile
所做的事情,而没有弄乱 self
:
+ (DateTracker*)unarchiveFromFile:(NSString *)filePath {
DateTracker *result = nil;
if ([[NSFileManager defaultManager] attributesOfFileSystemForPath:filePath error:NULL]) {
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
result = [unarchiver decodeObjectForKey:kDateDataKey];
[unarchiver finishDecoding];
[unarchiver release];
[data release];
}
return result;
}
关于ios - 释放使用 initFromFile 方法创建的对象时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3863488/