将核心数据警告的NSValueTransformer更改为NSSecureUnarchiveFromDataTransf



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

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

所以我读了这个(链接),并认为我需要将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'的前提。我很想知道我能做些什么来解决这个问题。

我认为您不需要重写+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作为transformable属性的自定义类,并将ImageToDataTransformer作为值转换器的名称。

让我们知道它是否有效。

相关内容

  • 没有找到相关文章

最新更新