将“NSManaged public var”设为可选布尔值
Posted
技术标签:
【中文标题】将“NSManaged public var”设为可选布尔值【英文标题】:Making an "NSManaged public var" an Optional Boolean 【发布时间】:2017-07-31 15:24:00 【问题描述】:如何将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
的属性。
【问题讨论】:
【参考方案1】:如果你使用@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")
【讨论】:
更正@NSManaged 类型必须与ObjC 兼容。但是,这里的问题不在于可选,而在于 Swift Bool 类型。 Swift 的 Bool 类型是一个对象,与 ObjC 的 BOOL 原始类型不兼容/不等价。【参考方案2】:Tom Harrington 的回答是正确的,@NSManaged 类型必须与 ObjC 一起使用。但是,问题不在于可选类型。 @NSManaged 类型可能是可选的,例如:
@NSManaged var someProperty: String?
这里的问题在于 Swift Bool 类型。 Swift 的 Bool 是一个对象,与 ObjC 的原始类型 BOOL 不同。对于具有布尔属性的 CoreData 实体,您应该使用 NSNumber?在代码中键入 @NSManaged 属性。然后,类似于 Tom 的回答,您可以设置一个单独的 Bool 访问器属性来获取/设置 @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 实体中布尔属性的 NSNumber。
【讨论】:
【参考方案3】:如果您将 Codegen 设置为手动,这可能是您遇到该问题的原因。您必须确保在创建NSObject
子类时所有属性都已预设,之后无需添加其他属性。
如果您在创建 NSObject
子类后尝试添加新属性,则会收到此错误。
我的解决方案:删除您的子类和属性文件并返回到您的 .xcdatamodeld
文件并使用您想要的所有属性重新生成它们。
【讨论】:
以上是关于将“NSManaged public var”设为可选布尔值的主要内容,如果未能解决你的问题,请参考以下文章
将字典键设为行,将字典值设为列,一个值作为列名,一个作为列值