核心数据可转换属性不适用于NSPredicate [英] Core Data Transformable attributes NOT working with NSPredicate

查看:76
本文介绍了核心数据可转换属性不适用于NSPredicate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常将 Transformable 用于核心数据属性,所以以后可以更改它们。

I often use Transformable for Core Data attributes, so I can change them later.

但是,如果我想使用 NSPredicate 来查找 NSManagedObject ,使用 uniqueKey ==%@ uniqueKey MATCHES [cd]%@

However, it seems like, if I want to use NSPredicate to find a NSManagedObject, using "uniqueKey == %@", or "uniqueKey MATCHES[cd] %@", it's not working as it should.

它总是会丢失匹配的对象,直到我将匹配对象的uniqueKey的属性更改为具有特定的类,例如 NSString NSNumber

It always misses matching objects, until I change the attributes of the uniqueKey of the matching object to have specific class like NSString, or NSNumber.

有人可以解释使用<$ c的局限性吗$ c> NSPredicate 具有 Transformable 属性?

Can someone explain the limitation of using NSPredicate with Transformable attributes?

推荐答案

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

Note: I'm not sure when/if this has changed since 5/2011 (from Scott Ahten's accepted answer), but you can absolutely search with NSPredicate on transformable attributes. Scott correctly explained why your assumptions were broken, but if Can someone explain the limitation of using NSPredicate with Transformable attributes? was your question, he implied that it is not possible, and that is incorrect.

由于Google是 核心数据可转换值搜索nspredicate (我为寻求灵感而进行的搜索)的第一笔Google匹配,因此我想添加我的工作答案。

Since the is the first google hit for "Core Data transformable value search nspredicate" (what I searched for trying to find inspiration), I wanted to add my working answer.

如何将NSPredicate与可转换属性一起使用

令人兴奋的答案:您需要对数据转换器保持精明。您需要将值从包含我称为原始标识信息的NSData转换,即可以用于重建对象的最小,最具标识性的字节集。长答案,...

Short, heady answer: you need to be smart about your data transformers. You need to transfrom the value to NSData that contains what I'll call "primitive identifying information", i.e. the smallest, most identifying set of bytes that can be used to reconstruct your object. Long answer, ...

首先,请考虑:


  • 您是否实际意味着要使用可变形属性?如果可以使用任何受支持的数据类型(甚至二进制数据),就可以使用它。

  • 您了解实际上是什么可转换属性吗?他们如何将数据与商店之间打包和解压缩?在非标准持久属性中查看苹果的文档。

    • 阅读以上内容后,问:隐藏受支持类型 backing attribute的自定义代码对您有用吗?可能使用该技术。

    • Did you actual mean to use a transformable attribute? If any supported data type -- even binary data -- will suffice, use it.
    • Do you understand what transformable attributes actually are? How they pack and unpack data to and from the store? Review Non-Standard Persistent Attributes in Apple's documentation.
      • After reading the above, ask: does custom code that hides a supported type "backing attribute" work for you? Possibly use that technique.

      现在,经过这些考虑,可转换的属性相当光滑坦白说,为Foo实例编写一个NSValueTransformer FooToData到NSData似乎比编写许多专门的自定义代码更干净。我还没有发现Core Data不知道需要使用已注册的NSValueTransformer转换数据的情况。

      Now, past those considerations, transformable attributes are rather slick. Frankly, writing an NSValueTransformer "FooToData" for Foo instances to NSData seemed cleaner than writing a lot of adhoc custom code. I haven't found a case where Core Data doesn't know it needs to transform the data using the registered NSValueTransformer.

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

      To proceed simply address these concerns:


      • 您是否告诉Core Data使用什么转换器?在表视图中打开核心数据模型,单击实体,单击属性,然后加载数据模型检查器窗格。在属性类型:可转换下,为您的转换器设置名称。

      • 使用默认转换器(同样,请参见先前的Apple文档)或编写自己的转换器-transformedValue:必须返回NSData。

        • NSKeyedUnarchiveFromDataTransformerName 是默认转换器,可能无法满足要求,或者可能会引入暂时性的实例数据,这些实例数据会使两个相似的对象在它们不同时变得不同相等。

        • Did you tell Core Data what transformer to use? Open the Core Data model in table view, click the entity, click the attribute, load the Data Model Inspector pane. Under "Attribute Type: Transformable", set "Name" to your transformer.
        • Use a default transformer (again, see the previous Apple docs) or write your own transformer -- transformedValue: must return NSData.
          • NSKeyedUnarchiveFromDataTransformerName is the default transformer and may not suffice, or may draw in somewhat-transient instance data that can make two similar objects be different when they are equal.

          您可能不会想要使用转换大量查询的数据操作-例如

          You probably don't want to use transforms heavily queried data operations - e.g. a large import where the primary key information uses transformers - yikes!

          最后,我只是用它来测试模型中高级对象属性的相等性使用NSPredicates-例如%K ==%@-可以正常工作。我没有尝试过各种匹配的术语,但是有时它们会起作用,而另一些却没有,我不会感到惊讶。

          And then in the end, I simply use this to test for equality for high-level object attributes on models with NSPredicates -- e.g. "%K == %@" -- and it works fine. I haven't tried some of the various matching terms, but I wouldn't be surprised if they worked sometimes, and others not.

          下面是一个NSURL的示例NSData转换器。为什么不只存储字符串?是的,很好-这是自定义代码掩盖存储属性的一个很好的例子。此示例说明了在字符串化URL中添加了一个额外的字节来记录它是否是文件URL,从而使我们知道在解压缩对象时要使用哪些构造函数。

          Here's an example of an NSURL to NSData transformer. Why not just store the string? Yeah, that's fine -- that's a good example of custom code masking the stored attribute. This example illustrates that an extra byte is added to the stringified URL to record if it was a file URL or not -- allowing us to know what constructors to use when the object is unpacked.

          // 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
          

          这篇关于核心数据可转换属性不适用于NSPredicate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆