问题描述
我有一个奇怪的问题,我不能看出,我有一个简单的实体与自定义NSManagedObject子类:
@objc(EntityTest)class EntityTest:NSManagedObject {
@NSManaged var crDate:NSDate
@NSManaged var name:String
@NSManaged var completed:Bool
@NSManaged var completedOn:NSDate
}
这是问题,我可以创建对象精细并设置所有的值并存储在数组中。然而,后来,当我尝试检索相同的对象,我可以设置所有的值,除了完成字段。我得到一个运行时错误说EXC_BAD_ACCESS,我可以读取值,只是不能设置它。
调试器指向:
0x32d40ae:je 0x32d4110; objc_msgSend + 108
0x32d40b0:movl(%eax),%edx
它被视为一个Objective-C类,并试图发送消息设置布尔值,我知道是有点搞笑CoreData最初表示为NSNumbers。
任何想法?我自己创建了类,不生成。
编辑:
entity.crDate = NSDate()//成功
entity.completed = false //失败
entity.completed.setValue(false,forKey:completed)//成功
所以为了设置bool,使用NSManagedObject的setValue工作而不是直接的setters,
更新:
检查这一点,看起来像第一次我从NSEntityDescription获取后设置值,它使用普通的Swift访问器方法。后来当我尝试访问同一个对象(它存储在一个数组),它试图将其视为一个Objective-C风格对象,并发送一个名为setCompleted的方法的消息。我想这是有道理的,因为我使用点符号来访问它,我使用的@objc指令。
我通过创建一个setCompleted方法,该方法我使用completed = newValue设置值,这使得递归调用回到setCompleted导致它崩溃...奇怪,所以在这一刻仍然不能没有正确的修复。它似乎只发生在Bools。
只有解决方法是使用NSManagedObject的setValueForKey方法。
如果您允许 Xcode 6 Beta 3 创建Swift文件,它将创建 CoreData
的 NSNumber
属性布尔
type。
不过,您可以使用Bool作为Swift类型,而不是NSNumber,虽然不使用点语法。
它将用 NSNumber
设置Swift Bool
,这可能会导致点语法中的错误。
为了使它显式,你应该使用 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将来会实现私有属性。
编辑:
如果您选中创建skalar类型甚至在自动创建的Swift文件中使用类型 Bool
!
所以我认为这是一个错误。 p>
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
}
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.
The debugger points to:
0x32d40ae: je 0x32d4110 ; objc_msgSend + 108
0x32d40b0: movl (%eax), %edx
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.
EDIT:
entity.crDate = NSDate() // succeeds
entity.completed = false // fails
entity.completed.setValue(false, forKey: "completed") //succeeds
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.
UPDATE:
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.
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.
Only workaround is use the "setValueForKey" method of NSManagedObject. Perhaps file this as a bug report?
If you let Xcode 6 Beta 3 create the Swift files for your entities, it will create NSNumber
properties for CoreData
s Boolean
type.
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.
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
.
Like so:
@NSManaged var snack: NSNumber
var isSnack: Bool {
get {
return Bool(snack)
}
set {
snack = NSNumber(bool: newValue)
}
}
Of course it would be cool to hide the other (NSNumber attribute), but be patient and Apple will implement private attributes in the future.
Edit:
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 - Bug?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!