使 "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 文件并使用您想要的所有属性重新生成它们。