2014-09-21 228 views
19

在Swift中使用Core Data时如何实现计算属性的任何建议?CoreData Swift和瞬态属性获取器

与生成的ManagedObject类,我试图重写消气,但我得到的错误:

'NSManaged' not allowed on computed properties

这意味着你不能覆盖的瞬态(计算值)属性,吸气。

在下面的代码示例中,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! 
    } 

} 

回答

5

“瞬时”和“计算”在你的意思上是不同的东西,是互相排斥的。

瞬态意味着该值存储在对象图上的内存中。计算意味着该值无处存储并在吸气剂中计算。两者都不同于传统的非瞬态属性,它存储在对象图上并保存到磁盘。

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

+0

它是托管对象模型中的一个属性。 Juts扩展,我试图复制一个苹果示例程序使用的技术 - 但是苹果示例是用Objective C编写的 - 实际上它是在Xcode(主细节应用程序)中提供的模板。 – 2014-09-21 17:35:23

+0

是的,但是ObjC不会执行'@ NSManaged' - 如果你想包装底层属性,你不应该在这里使用'@ NSManaged'。 '@ NSManaged'告诉编译器,在运行时会提供属性实现。在明确提供实现的同时使用'@ NSManaged'是一个矛盾。 – iluvcapra 2014-09-21 17:50:05

+0

好的谢谢。我会重新去除NSManaged。让你知道我如何得到:) – 2014-09-21 18:20:35

1

删除NSManaged属性。

+0

没有。对不起,那不是。代码的那部分是由Xcode生成的,所以我认为是正确的(或者至少是苹果的意图)。 – 2014-09-21 17:40:53

+1

不要假设;)如果它是暂时的,则不受管理。所以无论是应用还是你犯了一个错误 – 2014-09-21 17:42:51

+0

Xcode生成了代码,但是你正在编写隐藏底层属性的方法,你和代码生成器在思考不同的事情。 – iluvcapra 2014-09-21 17:53:59

44

首先,在数据模型中创建一个瞬态属性(section)。由于它是暂时的,因此它不是物理存储的,因此不存储在托管对象上下文中。

section属性如下所示:

enter image description here

实体如下所示:

enter image description here

类NSManagedObject子类应当已经计算 '部分' 属性。该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与通排序或动态失败等级:

enter image description here

我提出,可以在GitHub找到一个样本项目。

+0

https://gist.github.com/ivangodfather/86e0c3a02644f3520955 – Godfather 2014-12-30 20:54:27

+1

为我工作。 :)这个解决方案的不好之处在于你必须编辑自动生成的Core Data类。每次重新生成时,都必须重做修改。我将该部分放入扩展类中,但在重新生成类之后,仍然必须从生成的类中移除部分。 – 2015-04-25 19:22:27

+1

这个答案应该被接受!用日期而不是数字完美地工作。对于每个人都试图从“DateSectionTitles”苹果示例项目开始实施节日分隔的建议:请按照此答案代替!非常感谢@Bluehound – cdf1982 2015-04-29 16:55:10