【问题标题】:iPhone: Save boolean into Core DataiPhone:将布尔值保存到核心数据中
【发布时间】:2011-02-25 15:32:07
【问题描述】:

我已将我的核心数据属性之一设置为布尔值。现在,我需要设置它,但 XCode 一直告诉我它可能无法响应 setUseGPS。

[ride setUseGPS: useGPS.on];

在核心数据中设置布尔值的方法是什么?我所有的其他属性都是这样设置的,而且效果很好。那么,不知道为什么布尔值不能以这种方式设置?

【问题讨论】:

    标签: iphone core-data boolean uiswitch


    【解决方案1】:

    Core Data“没有”布尔类型(有,但它是一个 NSNumber)。

    所以设置相当于useGPS = YES。

    [entity setUseGPS:[NSNumber numberWithBool:YES]];
    

    反之亦然:

    BOOL isGPSOn = [[entity useGPS] boolValue];
    

    更新: 正如 SKG 所指出的,使用 Objetive-C 中的文字,您现在可以以更简单的方式完成:

    [entity setUseGPS:@YES];
    
    BOOL isGPSOn = entity.useGPS.boolValue;
    

    【讨论】:

    • 您也可以像这样设置值:object.isGPSOn = @YES;
    • 显然,在核心数据编辑器中创建新属性时,我实际上可以在下拉列表中看到布尔类型。那怎么办?
    【解决方案2】:

    作为接受答案的替代方法,您可以简单地将托管对象接口定义中的类型从 NSNumber* 更改为 BOOL,例如:

    @property (nonatomic) BOOL useGPS;   // Notice that the 'retain' is also removed as we're now dealing with a scalar rather than an NSObject
    

    here 讨论了各种替代方法,但Chris Hanson 的回答对我来说最有启发性,尤其是:

    如果你有一个数字属性 (包括一个布尔属性) 必需,您可以将其键入为 而是标量,Core Data 会做 正确的事情:

    @property (nonatomic) BOOL isDone;

    即使属性是可选的, 这仍然有效 - 它只会 将“不存在”与“假”混为一谈。

    对于更一致的 Cocoa 实现:

    你可能想做的另一件事 将属性命名为“完成”并且只是 将 getter 指定为“isDone”。那是 通常的 Cocoa 命名约定:

    @property(非原子,getter=isDone) BOOL 完成;

    然后你可以写“if (item.done) { ... }" 或 "item.done = NO;" 和 编译器仍会生成 -isDone 用于访问该属性。

    感谢克里斯,希望这对某人有所帮助。

    【讨论】:

    • 我在尝试此方法时看到 iOS 4.x 上的崩溃。消息如下:“属性 'bar' 是类 'Foo' 上的标量类型。无法为其生成 getter 方法。”我尝试在 Core Data 模型中将属性类型设置为布尔值,并且我也尝试过 Integer 16。无论哪种方式,我都会遇到相同的崩溃。我错过了什么吗?也许我会回到使用 NSNumber。
    • 据我所知,这不适用于 NSManagedObject 子类。
    【解决方案3】:

    为了补充 @RickiG 的答案,在 Swift 中从 Bool 和反之亦然创建 NSNumber 的方法是:

    let nsNumberFromBool = NSNumber(booleanLiteral: true) // or false
    let boolFromNSNumber = nsNumberFromBool.boolValue
    

    【讨论】:

      【解决方案4】:

      对此的“修复”(恕我直言,这是 Apple SDK 中的一个错误)是将以下代码添加到您的 CoreData 生成的类中。注意:如果您在一个类别中执行此操作,在一个单独的文件中,那么您不必每次在 Xcode 中重新生成 CoreData 类时都重新复制/粘贴它

      - (BOOL)useGPS
      {
          [self willAccessValueForKey:@"useGPS"];
          BOOL myuseGPS = [[self primitiveUseGPS] boolValue];
          [self didAccessValueForKey:@"useGPS"];
          return myuseGPS;
      }
      
      - (void)setUseGPS:(BOOL)newValue
      {
          [self willChangeValueForKey:@"useGPS"];
          [self setPrimitiveUseGPS:[NSNumber numberWithBool:newValue]];
          [self didChangeValueForKey:@"useGPS"];
      }
      

      【讨论】:

      • 这会在我编译时导致类型冲突。我应该更改现有 NSNumber 属性的类型吗?
      • @Daniel Wood - 不要更改现有类型:CoreData 要求它们是 NSNumber。编译警告很烦人 - 简单的解决方法是将上述两种方法重命名为“useGPSAsBool”和“setUseGPSAsBool”。注意:您仍然可以访问该属性,只是它现在称为“GPSAsBool”,例如“如果(myCoreDataObject.GPSAsBool)”
      • 在阅读了文档中的以下内容后,我决定不再理会这些,而是​​从代码中的 NSNumber 进行转换:“允许 Core Data 管理自己的存储的优势通常超过直接与标量值交互”developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/…
      • @Daniel - 您引用的文字指的是不同的问题。该文本不适用于这种情况——我们确实“允许 Core Data 管理它自己的存储”,我们只是添加了 2 个方便的方法以使其以 ObjectiveC 期望的方式使用布尔值。我希望 Apple 最终会在他们自己的代码中添加一个与此基本相同的修复程序。
      猜你喜欢
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多