Swift + CoreData:无法在NSManagedObject子类上设置Bool - Bug?

iQ.*_*iQ. 18 core-data objective-c ios swift

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

@objc(EntityTest) class EntityTest: NSManagedObject {

    @NSManaged var crDate: NSDate
    @NSManaged var name: String
    @NSManaged var completed: Bool
    @NSManaged var completedOn: NSDate
}
Run Code Online (Sandbox Code Playgroud)

这是问题,我可以创建对象,并设置所有值并存储在数组中.不过,当我尝试检索同一个对象时,我可以将所有值设置为"已完成"字段.我得到一个运行时错误说"EXC_BAD_ACCESS",我可以读取值,只是无法设置它.

调试器指向:

0x32d40ae:  je     0x32d4110                 ; objc_msgSend + 108
0x32d40b0:  movl   (%eax), %edx
Run Code Online (Sandbox Code Playgroud)

也许是一些问题,因为它被视为Objective-C类并尝试发送消息来设置boolean,我知道CoreData最初将它们表示为NSNumbers有点滑稽.

有任何想法吗?我自己创建了这个类,它没有生成.

编辑:

entity.crDate = NSDate() // succeeds
entity.completed = false // fails
entity.completed.setValue(false, forKey: "completed") //succeeds
Run Code Online (Sandbox Code Playgroud)

因此,对于设置bool,使用NSManagedObject的setValue但不是直接setter,但对于非bool属性,我可以使用setter设置它.

更新:

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

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

只有解决方法是使用NSManagedObject的"setValueForKey"方法.也许将此文件作为错误报告提交?

Bin*_*ian 17

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

在此输入图像描述

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


要使其明确,您应该使用类型NSNumber的实体中的属性Boolean类型.然后创建一个计算属性(在语言指南 - >属性 - >计算属性下的iBook Swift编程语言中)返回一个Swift Bool.所以永远不会存储一个Bool.

像这样:

@NSManaged var snack: NSNumber
var isSnack: Bool {
    get {
        return Bool(snack)
    }
    set {
        snack = NSNumber(bool: newValue)
    }
}
Run Code Online (Sandbox Code Playgroud)

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


编辑:

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

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


Coo*_*ham 0

我没有接触过swift,但是在Objective-C中,BOOL不是对象,也不可能是对象。它是一个原语,看起来您正试图告诉 Objective-C 类将 BOOL 视为对象。但我可能会弥补这一点,因为我不熟悉 @NSManaged 在幕后的作用。

https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/FoundationTypesandCollections/FoundationTypesandCollections.html