微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CoreData NSTransformer 奇怪之处

如何解决CoreData NSTransformer 奇怪之处

在我的 CoreData 实现中,我有许多可转换 (NSData) 属性为我存储 NSImage 数据。一切正常,但我对在我的应用程序启动期间发生的某些转换的重复性感到有些困惑。

下面是将 store 中的 NSData 转换为 NSImage(并返回)的代码,以及一些调试代码来捕获当它们从 store 出来时被转换的图像:

+ (NSArray *)allowedTopLevelClasses
{
    return @[[NSImage class]];
}

+ (Class)transformedValueClass
{
    return [NSImage class];
}

+ (BOOL)allowsReverseTransformation
{
    return YES;
}

// from CoreData Store -> user
- (NSImage *)transformedValue:(NSData *)value
{
    NSError *error = nil;
    NSImage *image = (!value) ? nil : [NSKeyedUnarchiver unarchivedobjectOfClass:[NSImage class]
                                                                        fromData:value
                                                                           error:&error];
    BOOL debug = YES;
    if (image && debug) {
        Nsstring *uuid = [[NSUUID UUID] UUIDString];
        NSURL *picDir = [[[NSFileManager defaultManager] URLsForDirectory:NSPicturesDirectory inDomains:NSUserDomainMask] firstObject];
        picDir = [picDir URLByAppendingPathComponent:[Nsstring stringWithFormat:@"tempPics/%@.png",uuid]];
        NSData *imageData = [image TIFFRepresentation];
        NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
        imageData = [imageRep representationUsingType:NSBitmapImageFileTypePNG
                                           properties:@{NSImageCompressionFactor : @1.0}];
        if (imageData && [imageData writetoFile:picDir.path atomically:YES])
            NSLog (@"Write location: %@",picDir.absoluteString);
    }
    return (!error && image) ? image : nil;
}

// from user -> CoreData Store
- (NSData *)reverseTransformedValue:(NSImage *)value
{
    NSError *error = nil;
    NSData *data = nil;
    if ([value isKindOfClass:[NSImage class]])
        data = [NSKeyedArchiver archivedDataWithRootObject:value
                                     requiringSecureCoding:NO
                                                     error:&error];
    return (!error) ? data : nil;
}

我在我的应用中使用 Cocoa 绑定,但是这个特定的转换器被同一个实体多次调用,所以我看到每个图像出现 3-4 个副本。

我开始走这条路是因为我注意到 NSKeyedUnarchiver:unarchivedobjectOfClass 方法上发生了一个小的内存泄漏。因此,我实现了自己的缓存方案(w/NSMutableDictionaary)以尝试跟踪(并减少冗余)转换。

这一小段代码一个 thumbViewImg getter(在 CoreData 实体的 Category 文件中),所有可可绑定都绑定到它,它从我的缓存中提取图像:

-(NSImage *)thumbViewImg {
    NSImage *img = [CoreDataimageCache getimageForEntity:self forKey:@"thumbViewImg"];
    return img;
}

我的转换器位于 thumbViewImgRaw 属性上,只有缓存根据需要引入。它不会在我的应用中以其他方式访问。

如果图像不在缓存中,则它为图像调用 CoreData getter/transformer thumbViewImgRaw。奇怪的是,这个缓存代码在启动结束时被调用了大约 50 次(正如预期的那样),并且它在第一次正确缓存未命中 50 次的情况下运行良好,然后当我刷新“页面”中的缩略图时随后出现 50 次点击我的应用。

但是在启动过程中,thumbViewImgRaw 转换器对于每个生成的对象至少调用 3 次。因此——换句话说,CoreData 为我的 50 个对象集合在内部调用thumbViewImgRaw 至少 150 次——而且我没有看到任何这些在我的缓存方案中运行。

而且——我已经尝试删除我正在做的任何预取,但没有任何效果

所以......我的两个问题:

  1. CoreData 在执行所有这些冗余转换时在做什么?
  2. 为什么会出现内存泄漏?当它与 Cocoa 绑定某些有关
  3. 时,试图在调试器中捕获它是很残酷的

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。