在Swift中使用Core Data时有关实现计算属性的任何建议吗?
使用生成的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!
}
}
答案 0 :(得分:46)
首先,在数据模型中创建一个瞬态属性(section
)。因为它是瞬态的,所以它不是物理存储的,因此不存储在托管对象上下文中。
此处显示section
属性:
此处显示实体:
类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
,其成绩按动态传递或失败排序:
我制作了一个可以在GitHub上找到的示例项目。
答案 1 :(得分:7)
"瞬态"和"计算"从某种意义上说,你的意思是不同的东西,是相互排斥的。
瞬态意味着该值存储在对象图上的内存中。计算意味着该值无处存储并在getter中计算。两者都不同于经典的非瞬态属性,它存储在对象图上并保存到磁盘中。
@NSManaged
只能应用于托管对象模型中有插槽的属性。
答案 2 :(得分:1)
删除NSManaged
属性。
答案 3 :(得分:1)
我已经在Swift中使用扩展名解决了这个问题,因此无需继承NSManagedObject的类,也不必为模型生成类文件。
因此,对于以上带有类Number
的示例,创建一个文件Number+Section.swift
,您可以在awakeFromFetch
中加载这样的瞬态属性值
import Foundation
extension Number {
public override func awakeFromFetch() {
super.awakeFromFetch()
section = number.intValue >= 60 ? "Pass" : "Fail"
}
}
我发现这种在Apple Core Data programming guide中加载瞬态字段的方式。
从对象重新初始化对象时,将调用awakeFromFetch。 持久性存储(在获取期间)。您可以将awakeFromFetch覆盖为 例如,建立瞬态值和其他缓存。