views:

990

answers:

2

I've got a Core Data model set up, with two entities in a one-to-many relationship (Items, and for each item, there can be multiple ResetDates). I'm pretty confident the model is set up correctly.

I can add new Items, and when doing so, add a new ResetDate (using the current date, with [NSDate date]). I can retrieve and display Items. What I'm having trouble with is retrieving and displaying the ResetDates.

Updated: It works now, thanks very much to the answerers below. Here's the code in question:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"resetDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1];

NSMutableArray *sortedResets = [[NSMutableArray alloc] initWithArray:[item.resets allObjects]];
[sortedResets sortUsingDescriptors:sortDescriptors];

NSDate *oldDate = [[sortedResets lastObject] resetDate];
if ( !oldDate ) {
 oldDate = [NSDate date];
}

NSInteger numberOfDays = [self timeIntervalWithStartDate:oldDate withEndDate:currentDate];  // This function works fine, when given two NSDate objects

daysSinceLabel.text = [NSString stringWithFormat:@"%d days", numberOfDays];
+1  A: 

Maybe replacing :

NSDate *oldDate = sortedResets[0];

with :

NSDate *oldDate = [sortedResets objectAtIndex:0];

will help. sortedResets is an NSArray object, not a C array ;)

dbbrian
I'd also recommend replacing the `initWithObjects:count:` method to create the sortDescriptors array with the simpler `initWithObject:` method.
Dave DeLong
Dave: This (`NSArray *sortDescriptors = [[NSArray alloc] initWithObject:sortDescriptor];`) doesn't work -- am I missing something?
Triz
Brian: Thanks for that, I forget sometimes that I'm not in C any more :)I think that gets me a lot closer, but now I'm getting crashes when a new Item is being created, and this gets called to display the newly-created row, but there isn't anything at index 0 yet. I thought the `if() {}` I inserted above should help, but it still dies. Any ideas?
Triz
@Triz - whoops, there's no `initWithObject:` method. You can use `+[NSArray arrayWithObject:]` and then not have to worry about releasing the sortDescriptors array.
Dave DeLong
+3  A: 

First, NSArray -objectAtIndex: is not returning nil if you pass it an index that is out of the bounds, it will raise an NSRangeException, when you're not sure about the index, and need to use -objectAtIndex:, you have to call the -count method before to check.

More importantly, an NSArray can't contain a nil value, as nil is not an object.

Then, no, it's not an NSDate object, when you ask item for it's resets relationship (item.resets), you get an NSSet that contain Reset managed objects in return, not NSDate objects, what you want is the resetDate attribute of the returned Reset managed objects, maybe something like this :

// NSArray -lastObject method return nil if the array is empty
// Sending messages to nil is Ok there, so we can call resetDate directly

NSDate *oldDate = [[sortedResets lastObject] resetDate];
if ( !oldDate ) {
    oldDate = [NSDate date];
}

Hope that help, and that my English is understandable...

dbbrian
Ahhhhh, okay, okay. That makes *much* more sense now -- it's a `Reset` object, not an `NSDate`. One problem: `resetDate` is a `@property` of the `Reset` class, not a method. I'm not terribly good with the syntax on these things yet... tried `[[sortedResets lastObject].resetDate]`, but that clearly isn't what I'm looking for...
Triz
@Triz since `resetDate` is declared as an `@property`, your Reset object *will* have `resetDate` and `setResetDate:` methods. That's the whole point of the `@property` syntax.
Dave DeLong
@Dave: Right, okay. I'm getting a warning on that line, though, that there's no `resetDate` method declared. I've got it in the `Reset` class header, as `@property (nonatomic, retain) NSDate *resetDate;`, and in the implementation as `@dynamic resetDate;`. Should it be `@synthesize` instead of `@dynamic`? The latter is how the CoreData template I started with was doing things, so I kept it.
Triz
Interestingly, the code works perfectly right now, despite that warning... Would like to get rid of it anyway, though. :)
Triz
Warning remedied by `#include`ing the Reset class. Yay!
Triz