Swift + CoreData:无法在 NSManagedObject 子类上设置 Bool - 错误? [英] Swift + CoreData: Can not set a Bool on NSManagedObject subclass - Bug?

查看:23
本文介绍了Swift + CoreData:无法在 NSManagedObject 子类上设置 Bool - 错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我似乎无法弄清楚的奇怪问题,我有一个带有自定义 NSManagedObject 子类的简单实体:

I have a little strange issue which I can't seem to figure out, I have a simple entity with a custom NSManagedObject subclass:

@objc(EntityTest) class EntityTest: NSManagedObject {

    @NSManaged var crDate: NSDate
    @NSManaged var name: String
    @NSManaged var completed: Bool
    @NSManaged var completedOn: NSDate
}

这就是问题所在,我可以很好地创建对象并设置所有值并存储在数组中.但是后来,当我尝试检索同一个对象时,我可以设置除已完成"字段之外的所有值.我收到一个运行时错误,提示EXC_BAD_ACCESS",我可以读取该值,只是无法设置它.

This is the problem, I can create the object fine and set the all the values and store in in an array. However late on, when I try to retrieve the same object, I can set all the values EXCEPT the "completed" field. I get a run-time error saying "EXC_BAD_ACCESS", I can read the value, just can not set it.

调试器指向:

0x32d40ae:  je     0x32d4110                 ; objc_msgSend + 108
0x32d40b0:  movl   (%eax), %edx

也许有些问题是因为它被视为一个 Objective-C 类并试图发送一条消息来设置布尔值,我知道这有点有趣,CoreData 最初将它们表示为 NSNumbers.

Maybe some issues due to it being treated as an Objective-C class and trying to send a message to set boolean which I know is a bit funny with CoreData originally representing them as NSNumbers.

有什么想法吗?这个类是我自己创建的,不是生成的.

Any ideas? I created the class myself, it is not generated.

entity.crDate = NSDate() // succeeds
entity.completed = false // fails
entity.completed.setValue(false, forKey: "completed") //succeeds

因此,对于设置 bool,使用 NSManagedObject 的 setValue 有效,但不能使用直接 setter,但对于非 bool 属性,我可以使用 setter 进行设置.

So for setting the bool, using the setValue of NSManagedObject works but not the direct setters, though for the non-bool properties, I can set it using the setters.

更新:

虽然更多地检查了这一点,但似乎是我第一次在从 NSEntityDescription 获取后设置值时,它使用了普通的 Swift 访问器方法.稍后,当我尝试访问同一个对象(存储在数组中)时,它尝试将其视为 Objective-C 样式对象,并为名为setCompleted"的方法发送消息.我想这是有道理的,因为我使用点符号来访问它并且我使用了 @objc 指令.

While checking this a bit more, it seems like the first time I set the value after getting from NSEntityDescription, it uses normal Swift accessor methods. Later on when I try to access the same object (which was stored in an array) it attempts to treat it as a Objective-C style object and sends a message for method named "setCompleted". I guess it makes sense since I use the dot notation to access it and I used the @objc directive.

我通过创建一个setCompleted"方法对此进行了测试,但是在该方法中我使用completed = newValue"设置了值,这使得递归调用回setCompleted"导致它崩溃......奇怪,所以在这个时刻仍然不能没有适当的修复.这似乎只发生在 Bools 中.

I tested this by creating a "setCompleted" method, however in the method I set the value using "completed = newValue" which makes a recursive call back to "setCompleted" causing it to crash... Strange, so at this moment still can't don't have a proper fix. It seems to only happen with Bools.

唯一的解决方法是使用 NSManagedObject 的setValueForKey"方法.也许将此作为​​错误报告提交?

Only workaround is use the "setValueForKey" method of NSManagedObject. Perhaps file this as a bug report?

推荐答案

如果您让 Xcode 6 Beta 3 为您的实体创建 Swift 文件,它将创建 NSNumberCoreDataBoolean 类型的属性.

If you let Xcode 6 Beta 3 create the Swift files for your entities, it will create NSNumber properties for CoreDatas Boolean type.

然而,您可以只使用 Bool 作为 Swift 类型而不是 NSNumber,虽然不使用点语法对我有用.它将使用 NSNumber 设置 Swift Bool,这可能会导致点语法中的错误.

You can however just use Bool as a Swift type instead of NSNumber, that worked for me without using the dot syntax though. It will set the Swift Bool with a NSNumber, that maybe leads to a bug in the dot syntax.

为了使其明确,您应该对具有 Boolean 类型的实体中的属性使用类型 NSNumber.然后创建一个计算属性(在 iBook The Swift 编程语言 中的 Language Guide -> Properties -> Computed Properties)返回一个 Swift Bool.所以永远不会真正存储 Bool.

To make it explicit you should use the type NSNumber for attributes in the entity with the Boolean type. Then create a computed property (in iBook The Swift programming language under Language Guide -> Properties -> Computed Properties) to return you a Swift Bool. So would never really store a Bool.

像这样:

@NSManaged var snack: NSNumber
var isSnack: Bool {
    get {
        return Bool(snack)
    }
    set {
        snack = NSNumber(bool: newValue)
    }
}

当然隐藏另一个(NSNumber 属性)会很酷,但请耐心等待,Apple 将来会实现私有属性.

如果您选中创建 skalar 类型框,它甚至会在自动创建的 Swift 文件中使用 Bool 类型!

If you check the box create skalar types it will even use the type Bool in the automatically created Swift file!

所以我认为这是一个错误.

So I think it is a bug.

这篇关于Swift + CoreData:无法在 NSManagedObject 子类上设置 Bool - 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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