【问题标题】:Changing NSValueTransformer to NSSecureUnarchiveFromDataTransformer for Core Data warning将 NSValueTransformer 更改为 NSSecureUnarchiveFromDataTransformer 以获取核心数据警告
【发布时间】:2021-05-17 20:22:55
【问题描述】:

在我的核心数据模式中,我在一个实体中有一个“可转换”属性,它使用NSValueTransformer,其目的是将 UIImage 转换为 NSData 并进行一些压缩。从这个属性,我最近开始收到关于使用NSKeyedUnarchiveFromData 的警告:

'NSKeyedUnarchiveFromData' 不应用于取消归档和 将在未来的版本中删除

所以我读到了这个 (link) 并认为我需要将 NSValueTransformer 更改为使用 NSSecureUnarchiveFromDataTransformer ...但是在进行更改之后(尽我所能从文章中理解)我无法让它工作,现在访问该属性时应用程序崩溃。

这是现有的NSValueTransformer

@interface ImageToDataTransformer : NSValueTransformer {
}

@implementation ImageToDataTransformer
+ (BOOL)allowsReverseTransformation {
    return YES;
}

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

- (id)transformedValue:(id)value {
    // for our smaller views this uses much less data and makes for faster syncing
    NSData *compressedData = UIImageJPEGRepresentation(value, 0.4);
    return compressedData;
}

- (id)reverseTransformedValue:(id)value {
    UIImage *uiImage = [[UIImage alloc] initWithData:value];
    NSData *data = (NSData *) value;
    //NSLog(@"reverseTransformedValue: image size: %@", [NSByteCountFormatter stringFromByteCount:data.length countStyle:NSByteCountFormatterCountStyleFile]);
    return uiImage;
}

所以我改为将其从NSSecureUnarchiveFromDataTransformer 改为子类,并将以下内容添加到实现中:

+ (NSArray<Class> *)allowedTopLevelClasses {
    return @[[ImageToDataTransformer class]];
}

+ (void)setValueTransformer:(nullable NSValueTransformer *)transformer forName:(NSValueTransformerName)name {
    NSLog(@"ImageToDataTransfer: calling setValueTransformer");
    [NSValueTransformer setValueTransformer:transformer forName:name];
}

+ (NSArray<NSValueTransformerName> *)valueTransformerNames {
    return @[@"ImageToDataTransformerName"];
}

然后,在访问 Core Data 持久存储之前,我“注册”转换器:

[ImageToDataTransformer setValueTransformer: [[ImageToDataTransformer alloc] init] forName:@"ImageToDataTransformerName"];

现在警告消失了,但是当读取图像时应用程序崩溃了:

-[__NSCFData _rasterizedImage]:无法识别的选择器发送到实例 0x7ff53c108800

如果我将变压器改回NSValueTransformer,它工作正常。所以我不确定我是否在实现中遗漏了一些东西,或者我误解了“NSSecureUnarchiveFromDataTransformer”的前提。很想知道我能做些什么来解决这个问题。

【问题讨论】:

    标签: core-data uikit nsvaluetransformer nssecurecoding


    【解决方案1】:

    我认为您不需要重写 +valueTransformerNames+setValueTransformer:forName: 类方法。

    从文档看来,它们不应该被覆盖,因为第一个类方法将返回在调用时实际注册的值转换器名称。第二种方法是您实际注册价值转换器的方式。所以你应该删除这两个覆盖的方法。

    您可以在您的应用中发生任何其他事情之前,在您的价值转换器的+load 类方法中注册您的价值转换器,如下所示:

    NSValueTransformerName const ImageToDataTransformerName = @"ImageToDataTransformer";
    
    + (void)load
    {
        [ImageToDataTransformer setValueTransformer:[[ImageToDataTransformer alloc] init]
                                            forName:ImageToDataTransformerName];
    }
    

    然后你重写+allowedTopLevelClasses 以返回允许的顶级可转换类,即 UIImage 类,如下所示:

    + (NSArray<Class> *)allowedTopLevelClasses
    {
        return @[[UIImage class]];
    }
    

    然后在您的 Core Data 架构中将 UIImage 作为可转换属性的自定义类,并将 ImageToDataTransformer 作为值转换器名称。

    让我们知道它是否有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      相关资源
      最近更新 更多