gpt4 book ai didi

xcode - 核心数据可转换属性不适用于 NSPredicate

转载 作者:可可西里 更新时间:2023-11-01 03:09:45 25 4
gpt4 key购买 nike

我经常将 Transformable 用于 Core Data 属性,因此我可以稍后更改它们。

但是,看起来,如果我想使用 NSPredicate 来查找 NSManagedObject,使用 "uniqueKey == %@",或 "uniqueKey MATCHES[cd] %@",它没有正常工作。

它总是会错过匹配对象,直到我将匹配对象的 uniqueKey 的属性更改为具有特定类,如 NSStringNSNumber

有人可以解释一下使用 NSPredicateTransformable 属性的限制吗?

最佳答案

注意:我不确定自 5/2011(来自 Scott Ahten 接受的答案)以来这何时/是否发生了变化,但您绝对可以使用 NSPredicate 搜索可转换属性。 Scott 正确地解释了为什么您的假设被打破,但是如果有人可以解释使用具有 Transformable 属性的 NSPredicate 的局限性吗? 是您的问题,他暗示这是不可能的,这是不正确的。

由于这是“Core Data 可转换值搜索 nspredicate”(我为寻找灵感而搜索的内容)的第一个 google 命中,我想添加我的工作答案。

如何使用具有可转换属性的 NSPredicate

简短而令人振奋的回答:您需要对数据转换器保持聪明。您需要将值转换为包含我称之为“原始标识信息”的 NSData,即可用于重建对象的最小、最具标识性的字节集。长答案,...

首先,考虑:

  • 您真的是想使用可变形属性吗?如果任何受支持的数据类型(甚至二进制数据)都足够,请使用它。
  • 您了解可转换属性的实际含义吗?他们如何打包和解包进出商店的数据?评论Non-Standard Persistent Attributes在苹果的文档中。
    • 阅读以上内容后,请问:隐藏受支持类型“支持属性”的自定义代码是否适合您?可能会使用该技术。

现在,抛开这些考虑因素,可变形属性相当巧妙。坦率地说,将 Foo 实例的 NSValueTransformer“FooToData”写入 NSData 似乎比编写大量临时自定义代码更干净。我还没有发现 Core Data 不知道它需要使用已注册的 NSValueTransformer 转换数据的情况。

要继续,只需解决这些问题:

  • 你告诉 Core Data 使用什么转换器了吗?在 TableView 中打开核心数据模型,单击实体,单击属性,加载数据模型检查器 Pane 。在“属性类型:可转换”下,将“名称”设置为您的转换器。
  • 使用默认转换器(同样,请参阅以前的 Apple 文档)或编写您自己的转换器 -- transformedValue:必须返回 NSData。
    • NSKeyedUnarchiveFromDataTransformerName 是默认的转换器,可能不够用,或者可能会引入一些短暂的实例数据,这会使两个相似的对象在相等时有所不同。
  • 转换后的值应该只包含——我称之为——“原始识别信息”。商店将比较字节,因此每个字节都很重要。
  • 您也可以在全局范围内注册您的转换器。我必须这样做,因为我实际上在应用程序的其他地方重复使用它们——例如NSString *name = @"FooTrans"; [NSValueTransformer setValueTransformer:[NSClassFromString(name) new] forName:name];

您可能不想使用转换大量查询的数据操作 - 例如主键信息使用转换器的大型导入 - 哎呀!

然后最后,我只是用它来测试具有 NSPredicates 的模型上高级对象属性的相等性——例如“%K == %@”——它工作正常。我没有尝试过一些不同的匹配术语,但如果它们有时有效而其他的无效,我不会感到惊讶。

这是一个 NSURL 到 NSData 转换器的例子。为什么不只存储字符串?是的,这很好——这是自定义代码屏蔽存储属性的一个很好的例子。这个例子说明了一个额外的字节被添加到字符串化的 URL 来记录它是否是一个文件 URL——让我们知道在对象被解包时使用什么构造函数。

// URLToDataTransformer.h - interface
extern NSString *const kURLToDataTransformerName;
@interface URLToDataTransformer : NSValueTransformer
@end

...

// URLToDataTransformer.m - implementation
#import "URLToDataTransformer.h"
NSString *const kURLToDataTransformerName = @"URLToDataTransformer";

@implementation URLToDataTransformer
+ (Class)transformedValueClass { return [NSData class]; }
+ (BOOL)allowsReverseTransformation { return YES; }

- (id)transformedValue:(id)value
{
if (![value isKindOfClass:[NSURL class]])
{
// Log error ...
return nil;
}
NSMutableData *data;
char fileType = 0;
if ([value isFileURL])
{
fileType = 1;
data = [NSMutableData dataWithBytes:&fileType length:1];
[data appendData:[[(NSURL *)value path] dataUsingEncoding:NSUTF8StringEncoding]];
}
else
{
fileType = -1;
data = [NSMutableData dataWithBytes:&fileType length:1];
[data appendData:[[(NSURL *)value absoluteString] dataUsingEncoding:NSUTF8StringEncoding]];
}
return data;
}

- (id)reverseTransformedValue:(id)value
{
if (![value isKindOfClass:[NSData class]])
{
// Log error ...
return nil;
}

NSURL *url = nil;
NSData *data = (NSData *)value;
char fileType = 0;
NSRange range = NSMakeRange(1, [data length]-1);
[data getBytes:&fileType length:1];
if (1 == fileType)
{
NSData *actualData = [data subdataWithRange:range];
NSString *str = [[NSString alloc] initWithData:actualData encoding:NSUTF8StringEncoding];
url = [NSURL fileURLWithPath:str];
}
else if (-1 == fileType)
{
NSData *actualData = [data subdataWithRange:range];
NSString *str = [[NSString alloc] initWithData:actualData encoding:NSUTF8StringEncoding];
url = [NSURL URLWithString:str];
}
else
{
// Log error ...
return nil;
}

return url;
}
@end

关于xcode - 核心数据可转换属性不适用于 NSPredicate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6104566/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com