使 "NSManaged public var" 成为可选的布尔值
Making an "NSManaged public var" an Optional Boolean
如何使 NSManaged public var
成为可选的布尔值?当我输入以下内容时:
import Foundation
import CoreData
import UIKit
extension SomeClass {
@NSManaged public var isLiked: Bool?
@NSManaged public var isDisliked: Bool?
}
我收到错误:
属性不能被标记为@NSManaged,因为它的类型不能在Objective-C
中表示
我要的是属性,既不能是liked
,也不能是disliked
。
如果你使用@NSManaged
,你必须遵守它的规则。这些规则包括使用没有选项的 ObjC。但是您不必使用 @NSManaged
,即使在使用 Core Data 时也是如此。只要您实现自己的访问器,就可以放弃它。类似于:
public var isLiked : Bool? {
get {
willAccessValue(forKey: "isLiked")
let isLiked = primitiveValue(forKey: "isLiked") as! Int64
didAccessValue(forKey: "isLiked")
return isLiked
}
set {
willChangeValue(forKey: "isLiked")
setPrimitiveValue(newValue, forKey: "isLiked")
didChangeValue(forKey: "isLiked")
}
}
Tom Harrington 的回答是正确的,@NSManaged 类型必须与 ObjC 一起使用。但是,问题不在于可选类型。 @NSManaged 类型可以是可选的,例如:
@NSManaged var someProperty: String?
此处的问题与 Swift Bool 类型有关。 Swift 的 Bool 是一个对象,与 ObjC 原始类型 BOOL 不同。对于带有布尔值 属性 的 CoreData 实体,您应该使用 NSNumber?在您的代码中键入 @NSManaged 属性。然后,类似于 Tom 的回答,您可以设置一个单独的 Bool 访问器 属性 到 get/set @NSManaged NSNumber 属性,例如:
// the "liked" property is a Boolean attribute in your CoreData entity
@NSManaged var liked: NSNumber?
var isLiked: Bool? {
get { return Bool(exactly: liked) }
set { liked = NSNumber(booleanLiteral: newValue) }
}
isLiked
属性 将允许您在代码中像使用 Bool 一样使用它,但在底层,CoreData 将值存储为 CoreData 实体中 Boolean 属性的 NSNumber。
如果您将 Codegen 设置为手动,这可能是您遇到该问题的原因。您必须确保在创建 NSObject
子类时所有属性都是预设的,之后不需要添加其他属性。
如果您在已经创建 NSObject
子类之后尝试添加新属性,那么您将收到此错误。
我的解决方案:删除子类和属性文件并返回到 .xcdatamodeld
文件并使用您想要的所有属性重新生成它们。
如何使 NSManaged public var
成为可选的布尔值?当我输入以下内容时:
import Foundation
import CoreData
import UIKit
extension SomeClass {
@NSManaged public var isLiked: Bool?
@NSManaged public var isDisliked: Bool?
}
我收到错误:
属性不能被标记为@NSManaged,因为它的类型不能在Objective-C
中表示我要的是属性,既不能是liked
,也不能是disliked
。
如果你使用@NSManaged
,你必须遵守它的规则。这些规则包括使用没有选项的 ObjC。但是您不必使用 @NSManaged
,即使在使用 Core Data 时也是如此。只要您实现自己的访问器,就可以放弃它。类似于:
public var isLiked : Bool? {
get {
willAccessValue(forKey: "isLiked")
let isLiked = primitiveValue(forKey: "isLiked") as! Int64
didAccessValue(forKey: "isLiked")
return isLiked
}
set {
willChangeValue(forKey: "isLiked")
setPrimitiveValue(newValue, forKey: "isLiked")
didChangeValue(forKey: "isLiked")
}
}
Tom Harrington 的回答是正确的,@NSManaged 类型必须与 ObjC 一起使用。但是,问题不在于可选类型。 @NSManaged 类型可以是可选的,例如:
@NSManaged var someProperty: String?
此处的问题与 Swift Bool 类型有关。 Swift 的 Bool 是一个对象,与 ObjC 原始类型 BOOL 不同。对于带有布尔值 属性 的 CoreData 实体,您应该使用 NSNumber?在您的代码中键入 @NSManaged 属性。然后,类似于 Tom 的回答,您可以设置一个单独的 Bool 访问器 属性 到 get/set @NSManaged NSNumber 属性,例如:
// the "liked" property is a Boolean attribute in your CoreData entity
@NSManaged var liked: NSNumber?
var isLiked: Bool? {
get { return Bool(exactly: liked) }
set { liked = NSNumber(booleanLiteral: newValue) }
}
isLiked
属性 将允许您在代码中像使用 Bool 一样使用它,但在底层,CoreData 将值存储为 CoreData 实体中 Boolean 属性的 NSNumber。
如果您将 Codegen 设置为手动,这可能是您遇到该问题的原因。您必须确保在创建 NSObject
子类时所有属性都是预设的,之后不需要添加其他属性。
如果您在已经创建 NSObject
子类之后尝试添加新属性,那么您将收到此错误。
我的解决方案:删除子类和属性文件并返回到 .xcdatamodeld
文件并使用您想要的所有属性重新生成它们。