我有一个似乎无法弄清楚的奇怪问题,我有一个带有自定义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文件,它将为NSNumber
的CoreData
类型创建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/