将“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”设为可选布尔值的主要内容,如果未能解决你的问题,请参考以下文章

将字典键设为行,将字典值设为列,一个值作为列名,一个作为列值

如何用python来改这列值。将小于30的设为0,大于30的设为1,谢谢各位大神

将主要方法的参数设为最终[关闭]

将 println 设为宏有啥好处?

如何将 Django 模型设为只读?

YOURLS 将“缩短”接口设为私有