Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
732 views
in Technique[技术] by (71.8m points)

core data - CoreData Swift and transient attribute getters

Any advice on implementing calculated attributes when using Core Data in Swift?

with the generated ManagedObject class, I tried to override the getter but I get the error:

'NSManaged' not allowed on computed properties

which implies you cannot override the getter for a transient (calculated) attribute.

In the code sample below, dateDue is defined as a transient attribute in my model.

Please note that the @NSManaged lines were generated by Xcode - not added by me.

@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!
    }

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, in the data model create a transient attribute (section). Because it is transient, it is not physically stored and thus not stored in the managed object context.

The section attribute is shown here:

enter image description here

The entity is shown here:

enter image description here

The class NSManagedObject subclass should have computed 'section' attribute. The NSManagedObject subclass demonstrating how to accomplish this is shown here:

class Number: NSManagedObject {

    @NSManaged var number: NSNumber

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

Then you must set sectionForKeyPath in the NSFetchedResultsController initializer to be the transient attribute key in the data model and the cache name if desired.

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
}

The result is a UITableViewController with grades sorted by pass or fail dynamically:

enter image description here

I made a sample project that can be found on GitHub.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...