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

@objc(EntityTest) class EntityTest: NSManagedObject {

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

这是问题,我可以很好地创建对象并设置所有值并存储在数组中。但是,稍后,当我尝试检索同一对象时,可以设置除“completed”字段之外的所有值。我收到一个运行时错误消息“EXC_BAD_ACCESS”,我可以读取该值,但是无法设置它。

调试器指向:
0x32d40ae:  je     0x32d4110                 ; objc_msgSend + 108
0x32d40b0:  movl   (%eax), %edx

也许是由于将其视为一个Objective-C类并试图发送一条消息来设置 bool 值而引起的一些问题,我知道对于CoreData最初将它们表示为NSNumbers有点可笑。

有任何想法吗?我自己创建了该类,但未生成。

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

因此对于设置 bool 值,可以使用NSManagedObject的setValue起作用,但不能使用直接 setter ,尽管对于非 bool 型属性,我可以使用 setter 进行设置。

更新:

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

我通过创建一个“setCompleted”方法对此进行了测试,但是在该方法中,我使用“completed = newValue”设置了值,这导致递归调用“setCompleted”,从而导致崩溃...奇怪,因此目前仍然可以没有适当的解决方法。这似乎只发生在 bool 斯。

唯一的解决方法是使用NSManagedObject的“setValueForKey”方法。也许将其归档为错误报告?

最佳答案

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

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

为了明确起见,您应该将NSNumber类型用于Boolean类型的实体中的属性。然后创建一个计算属性(在iBook中,语言指南->属性->计算属性下的Swift编程语言)为您返回一个Swift Bool。因此永远不会真正存储Bool
像这样:

@NSManaged var snack: NSNumber
var isSnack: Bool {
    get {
        return Bool(snack)
    }
    set {
        snack = NSNumber(bool: newValue)
    }
}
当然,隐藏另一个(NSNumber属性)会很酷,但是要耐心等待,Apple将来会实现私有(private)属性。

编辑:
如果选中创建skalar类型框,它甚至会在自动创建的Swift文件中使用Bool类型!
所以我认为这是一个错误。

关于ios - Swift + CoreData : Can not set a Bool on NSManagedObject subclass - Bug?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24333507/

10-09 07:03
查看更多