ios - 释放使用 initFromFile 方法创建的对象时崩溃

标签 ios objective-c memory-management nscoding

我创建了一个名为“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/

相关文章:

objective-c - UIButton UIControlEventTouchUpInside 不会触发,但 UIControlEventTouchDown 会触发

iphone - Ios NSDictionary 数组 - 分组值和键

c++ - C/C++ Windows 或 Linux 将随机内存块映射为连续顺序

c - 移动指针后 C 中的内存泄漏问题(释放的到底是什么?)

iphone - 在 Overlays 可见时隐藏 MKMapView

ios - 如何在不显示确认屏幕的情况下直接发送消息?

ios - 只获取 cloudkit 中的特定字段?

objective-c - 如何在 C/Objective C 中实现位数组

objective-c - NSButton 不会设置字体 : when layer backed

c - 在 C 中动态分配二维数组