I don't know if it is possible to change where the nil dates are sorted to in the NSFetchedResultsController. However, I do have a suggestion along the lines of your "hack" of changing nil dates to a future time. Specifically, I would create a new transient property for your entity that returns a modified date.
Basically, the custom getter for that property would retrieve the date and then check if it is nil. If so, it would return the latest future date that NSDate supports. This would allow the NSFetchedResultsController to sort the results in the way you want Using transient properties is how lists with sections using the first letter of a person's last name (a la the Contacts App) are created.
A method for doing that is described here For example: THIS ATTRIBUTE GETTER GOES IN YOUR OBJECT MODEL FOR THE // TRANSIENT PROPERTY modifedDate - (NSDate *) modifiedDate { self willAccessValueForKey:@"date"; NSDate * date = self date; if(date == nil) date = // Set as furthest future date. Self didAccessValueForKey:@"date"; return date }.
I don't know if it is possible to change where the nil dates are sorted to in the NSFetchedResultsController. However, I do have a suggestion along the lines of your "hack" of changing nil dates to a future time. Specifically, I would create a new transient property for your entity that returns a modified date.
Basically, the custom getter for that property would retrieve the date and then check if it is nil. If so, it would return the latest future date that NSDate supports. This would allow the NSFetchedResultsController to sort the results in the way you want.
Using transient properties is how lists with sections using the first letter of a person's last name (a la the Contacts App) are created. A method for doing that is described here. For example: // THIS ATTRIBUTE GETTER GOES IN YOUR OBJECT MODEL FOR THE // TRANSIENT PROPERTY modifedDate - (NSDate *) modifiedDate { self willAccessValueForKey:@"date"; NSDate * date = self date; if(date == nil) date = // Set as furthest future date.
Self didAccessValueForKey:@"date"; return date; }.
As I understand it, a transient property can be used for the sectionNameKeyPath (and in fact, I do use a transient property for that) but cannot be used for the sort descriptor as the sorting is done by SQLite at the database level and that transient property does not exist in the database. Please feel free to correct me if I have misunderstood this. I will on the other hand use a transient property to "interpret" the hack date and return nil when that particular date is encountered.
This will prevent me from having to process the fake date in other parts of my code. – glorifiedHacker Mar 27 '10 at 7:17 My mistake. You are correct that a transient property cannot be used as a sort descriptor.
– Tim Isganitis Mar 27 '10 at 17:32 If sorting must be done in the database, then you could add a hasDate boolean property to your object model and sort by that first and then by the date. However, in addition to adding redundancy to the database, I also assume this is the "compound sorting" approach you say you want to avoid in your original question. – Tim Isganitis Mar 27 '10 at 17:44 Yes, that's what I meant by compound sorting.
The sectionNameKeyPath has to match the sort ordering of the first sort descriptor in the fetch request, so sorting by hasDate first would give me at best two sections in my tableView. – glorifiedHacker Mar 27 '10 at 19:16.
I decided to go with the "hack" fix, because I didn't want to incur the overhead of having the entire object graph loaded in memory that comes with using the binary store. Instead of storing nil when the user doesn't set a date, I store the result of a "noDate" class method.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.