0

我创建了一个符合 NSCoding 的名为“DateTracker”的对象,因此它包含 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];

我的应用程序崩溃。

当我使用性能工具运行应用程序来检查内存泄漏时,它抱怨我没有释放这个对象。

任何想法我做错了什么?

4

1 回答 1

2

这一行:

self = [unarchiver decodeObjectForKey:kDateDataKey];

会给你带来麻烦。

您正在做的是分配一个 DateTracker 对象 ( [DateTracker alloc]),然后创建一个新的 DateTracker 对象 (by -decodeObjectForKey:) 并使“self”指针指向新对象。这样做有两个问题:

  • 你不再有对旧对象的引用,所以它被泄露了
  • 新对象没有被保留,所以它会消失(或者如果你试图释放它会导致崩溃)

我会说让对象替换自身的方法有点可疑。也许您最好将filePath变量移到DateTracker对象之外,并通过以下方式取消归档:

DateTracker *currentTracker = [[DateTracker unarchiveFromFile:filePath] retain];

whereunarchiveFromFile:是一个类方法,它基本上做了什么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;
}
于 2010-10-05T12:37:05.873 回答