存储的属性需要一个初始值或者应该是@NSManaged

Posted

技术标签:

【中文标题】存储的属性需要一个初始值或者应该是@NSManaged【英文标题】:Stored property requires an initial value or should be @NSManaged 【发布时间】:2015-04-05 00:25:33 【问题描述】:

我正在尝试将 Apple's sample code 转换为为 Core Data 创建自定义部分标识符,以便将表视图中的部分从 Objective-C 正确排序/标记为 Swift。他们为声明为@dynamic 的非瞬态属性实现了一个设置器,因此他们可以在时间更改时使标识符无效。我以为我会在 @NSManaged 属性上使用 didSet,但 Xcode 会抛出错误:Stored property requires an initial value or should be @NSManaged

如何适当地转换它以获得所需的行为?

@property (nonatomic) NSDate *primitiveTimeStamp;
@property (nonatomic) NSString *primitiveSectionIdentifier;

@dynamic title, timeStamp, primitiveTimeStamp, sectionIdentifier, primitiveSectionIdentifier;

- (void)setTimeStamp:(NSDate *)newDate 
    // If the time stamp changes, the section identifier become invalid.
    [self willChangeValueForKey:@"timeStamp"];
    [self setPrimitiveTimeStamp:newDate];
    [self didChangeValueForKey:@"timeStamp"];

    [self setPrimitiveSectionIdentifier:nil];

我试过了:

var primitiveTimeStamp: NSDate?
var primitiveSectionIdentifier: String?

@NSManaged var timeStamp: NSDate  //error here
    didSet 
        self.willChangeValueForKey("timeStamp")
        self.primitiveDate = timeStamp
        self.didChangeValueForKey("timeStamp")

        self.primitiveSectionIdentifier = nil
    

我还尝试取消 @NSManaged 并仅使用 var timeStamp: NSDate!,然后将代码放入 didSet,这对于第一次启动实际上非常有用 - 我可以创建一个对象并将其存储并在表中的适当部分。但在随后的启动中,timeStamp 属性为nil,因此应用程序在尝试生成sectionIdentifier 时崩溃。

【问题讨论】:

timeStamp 是临时属性吗?如果没有,为什么不使用NSFetchedResultsController?它允许您将数据分类为多个部分... @POB no timeStamp 不是瞬态的,我正在使用获取的结果控制器,但我需要一个名为 sectionIdentifier 的瞬态属性来获取所需的标识符,以便对其进行正确排序。 【参考方案1】:

timeStamp 您定义的是存储属性而不是计算属性。计算属性可能没有 didSet/didGet 观察者。

您不需要为未覆盖的计算属性定义属性观察器,因为您可以直接在计算属性的设置器中观察并响应对其值的更改。

var primitiveTimeStamp: NSDate?
var primitiveSectionIdentifier: String?

var timeStamp: NSDate 
  get 
    return self.primitiveDate
  

  set 
    self.willChangeValueForKey("timeStamp")
    self.primitiveDate = newValue
    self.didChangeValueForKey("timeStamp")

    self.primitiveSectionIdentifier = nil
  

由于计算属性应该只有一个 getter,或同时有 setter/getter,因此您还必须设置 getter。

我不是在测试代码,但它们可能会解决你的问题。

PS:如果你想为你的计算属性设置属性观察者,你可以子类化你的类并将属性观察者添加到继承的属性中。

【讨论】:

你会在 getter 中返回什么? @RobNapier 谢谢,使用该设置,它似乎可以正常工作。

以上是关于存储的属性需要一个初始值或者应该是@NSManaged的主要内容,如果未能解决你的问题,请参考以下文章

一个托管对象上下文的两个持久存储 - 可能吗?

如何使用 Java 属性文件?

构造方法

Swift 学习笔记 (初始化)

自动属性无法在 C# 实例构造函数中初始化

Swift 实践:属性