Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data NSTimeInterval using an accessor directly is buggy

I'm setting an NSTimeInterval using setValueForKey within an NSManagedObject Subclass, the value gets set correctly, and is also correct when it is retrieved using valueForKey, however, if an accessor is used directly, it returns an incorrect value. Here is a code sample that demonstrates the issue

let date = NSDate() //NSTimeIntervalSince1970 = 1447054145.15281
self.setValueForKey(date, "dateLastSynced")

self.valueForKey("dateLastSynced") //= 1447054145.15281
self.dateLastSynced // !!ERROR Incorrect value = 468746945.152815

Strangely enough, if the dateLastSynced is converted to an NSDate, everything works perfectly.

Any ideas on whats happening?

like image 740
Salman Hasrat Khan Avatar asked Jan 08 '23 05:01

Salman Hasrat Khan


2 Answers

A scalar property of type NSTimeInterval for a Core Data Date property represents the time in seconds since the reference date Jan 1, 2001. The Core Data generated accessor methods transparently convert between NSTimeInterval and NSDate.

Therefore you set a value using the scalar accessor with

obj.dateLastSynced = date.timeIntervalSinceReferenceDate

and you retrieve the value with

let date = NSDate(timeIntervalSinceReferenceDate: obj.dateLastSynced)

This gives the same results as the Key-Value Coding methods

// Set:
obj.setValueForKey(date, "dateLastSynced")
// Get:
let date = obj.valueForKey("dateLastSynced")
like image 112
Martin R Avatar answered Jan 19 '23 00:01

Martin R


Assigning to self.valueForKey("dateLastSynced") won't work; it's not an lvalue. You need to use setValueForKey.

Also, if the dateLastSynced is a date property, you cannot assign it a double value and expect it to work. Use

self.setValue(NSDate(timeIntervalSinceReferenceDate: <value>), forKey:"dateLastSynced")
like image 29
Aderstedt Avatar answered Jan 19 '23 00:01

Aderstedt