2014-09-21 462 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