Core data coredataswift和transient属性获取程序

Core data coredataswift和transient属性获取程序,core-data,swift,Core Data,Swift,在Swift中使用核心数据时,对实现计算属性有何建议 使用生成的ManagedObject类,我试图重写getter,但出现错误: 计算属性上不允许使用“NSManaged” 这意味着您不能覆盖瞬态(计算)属性的getter 在下面的代码示例中,dateDue在我的模型中被定义为瞬态属性 请注意,@NSManaged行是由Xcode生成的,不是我添加的 @NSManaged var timeStamp: NSDate @NSManaged var dateDue: String { g

在Swift中使用核心数据时,对实现计算属性有何建议

使用生成的ManagedObject类,我试图重写getter,但出现错误:

计算属性上不允许使用“NSManaged”

这意味着您不能覆盖瞬态(计算)属性的getter

在下面的代码示例中,
dateDue
在我的模型中被定义为瞬态属性

请注意,@NSManaged行是由Xcode生成的,不是我添加的

@NSManaged var timeStamp: NSDate
@NSManaged var dateDue: String { 
    get {

        self.willAccessValueForKey("dateDue")
        var ddtmp  = self.primitiveValueForKey("dateDue") as String?
        self.didAccessValueForKey("dateDue")

        if (ddtmp == nil)
        {

            let calendar = NSCalendar.currentCalendar()

            let components = calendar.components((NSCalendarUnit.YearCalendarUnit | NSCalendarUnit.MonthCalendarUnit ) , fromDate: self.timeStamp)
            ddtmp = "\(components.year * 1000 + components.month)"
            self.setPrimitiveValue(ddtmp, forKey: "dateDue")

        }



        return ddtmp!
    }

}
你所指的“瞬时”和“计算”是不同的东西,是相互排斥的

瞬态意味着该值存储在对象图的内存中。Computed意味着该值不存储在任何地方,而是在getter中计算。两者都不同于存储在对象图上并保存到磁盘的经典非瞬态属性


@NSManaged
只能应用于在托管对象模型中具有插槽的属性。

删除
NSManaged
属性。

首先,在数据模型中创建一个临时属性(
部分
)。因为它是暂时的,所以不会物理存储,因此也不会存储在托管对象上下文中

部分
属性如下所示:

class Number: NSManagedObject {

    @NSManaged var number: NSNumber

    var section: String? {
        return number.intValue >= 60 ? "Pass" : "Fail"
    }
}

实体如下所示:

class Number: NSManagedObject {

    @NSManaged var number: NSNumber

    var section: String? {
        return number.intValue >= 60 ? "Pass" : "Fail"
    }
}

类NSManagedObject子类应具有计算的“section”属性。演示如何完成此任务的
NSManagedObject
子类如下所示:

class Number: NSManagedObject {

    @NSManaged var number: NSNumber

    var section: String? {
        return number.intValue >= 60 ? "Pass" : "Fail"
    }
}
然后,必须将NSFetchedResultsController初始值设定项中的
sectionForKeyPath
设置为数据模型中的临时属性键,并根据需要设置缓存名称

override func viewDidLoad() {
        super.viewDidLoad()

        fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: "section", cacheName: "Root")
        fetchedResultsController?.delegate = self
        fetchedResultsController?.performFetch(nil)

        tableView.reloadData()
}

func fetchRequest() -> NSFetchRequest {

    var fetchRequest = NSFetchRequest(entityName: "Number")
    let sortDescriptor = NSSortDescriptor(key: "number", ascending: false)

    fetchRequest.predicate = nil
    fetchRequest.sortDescriptors = [sortDescriptor]
    fetchRequest.fetchBatchSize = 20

    return fetchRequest
}
结果是一个
UITableViewController
,其等级按通过或失败动态排序:


我制作了一个可以在上找到的示例项目。

我已经用Swift解决了这个问题,并提供了一个扩展,因此不需要对NSManagedObject进行子类化,也不必为我的模型生成类文件

因此,对于上面带有class
Number
的示例,创建一个文件
Number+节。swift
您可以在
awakeFromFetch

import Foundation    
extension Number {
    public override func awakeFromFetch() {
        super.awakeFromFetch()
        section = number.intValue >= 60 ? "Pass" : "Fail"
    }
}
我在苹果电脑中找到了这种加载瞬态场的方法

awakeFromFetch在从对象重新初始化对象时调用 持久存储(在获取期间)。您可以将awakeFromFetch重写为, 例如,建立瞬态值和其他缓存


它是托管对象模型中的一个属性。为了扩展,我正在尝试复制一个苹果示例程序使用的技术-但是苹果示例是用Objective C编写的-事实上它是用Xcode(master-detail应用程序)交付的模板.是的,但ObjC不执行
@NSManaged
——如果您试图包装底层属性,则不应在此处使用
@NSManaged
@NSManaged
告诉编译器将在运行时延迟提供属性实现。在显式提供实现的同时使用
@NSManaged
是一种矛盾。好的,谢谢。我将重新讨论删除NSM。让你知道我是如何相处的:)不。对不起,不是这样的。这部分代码是由Xcode生成的,所以我认为是正确的(或者至少是苹果的预期)如果它是暂时的,就不会被管理。因此,要么应用,要么你犯了一个错误,Xcode生成了代码,但你正在编写一个隐藏底层属性的方法,你和代码生成器的想法不同。明白你的意思了吗。我将尝试不使用NSManaged——我想我必须对Xcode生成的内容更加怀疑一点。@DaijDjan完全正确。在这种情况下应该删除。为我工作。:)此解决方案的缺点是必须编辑自动生成的核心数据类。每次重新生成时,都必须重新进行修改。我将节放在扩展类中,但在重新生成类后,我仍然必须从生成的类中删除节。这个答案应该被接受!用日期而不是数字对我来说非常有效。对于每个试图从“DateSectionTitles”苹果示例项目开始按日期实现节分隔的人,一个建议是:遵循以下答案!非常感谢@BluehoundI无法将其与swift 4/iOS 11配合使用。有人有类似的问题吗?@webventil找到了解决办法。需要在属性声明前面添加@objc我认为这个答案没有抓住要点。关键是瞬态核心数据属性仍然会为您生成一个getter和setter。您可以编辑机器生成的核心数据实体文件,使属性为只读而不是复制(即读写),然后在用户可编辑的实体生成文件中写入自己的getter,但任何涉及编辑机器生成文件的内容都不是一个好的解决方案。一个更好的答案可能是:忘记拥有一个暂时的属性。只需在人类可编辑CD生成的文件中创建一个getter,计算值。如果将Codegen设置为“类定义”,则此方法有效。感谢《解决方案核心数据指南》对此进行了清晰的解释。虽然它基本上可以正常工作,但当将NSFetchedResultsController与表视图结合使用时,这不是一个好的解决方案:初始表部分是正确的,但当您更新基础数据时,显然不会再次调用awakeFromFetch。这是一个很好的答案,特别是因为允许避免类生成只是为了有一个瞬态属性!比过去容易多了,谢谢!