I have added a category to my NSManagedObject IBCompany, which should retrieve a specific time period, which is one of the IBCompany’s relationships, based on a simple date comparison.
When I run the following code, the NSArray sortedFinPeriodsDesc contains the faulted periods in the correct sorted order. However, when accessing them in the for each loop, each of the periods returns nil for its attributes, and in particular, nil for its EndDate. For this reason my method lastReportedPeriodforDate always returns nil, which is an error.
#import "IBCompany+FinstatAccessors.h"
@implementation IBCompany (FinstatAccessors)
NSArray *sortedFinPeriodsDesc;
- (IBFinPeriod*)lastReportedPeriodforDate:(NSDate*)date;
{
if ( !sortedFinPeriodsDesc ) {
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"EndDate" ascending:NO];
sortedFinPeriodsDesc = [self.finperiod sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
}
IBFinPeriod *lastPeriod;
for (IBFinPeriod *finPeriod in sortedFinPeriodsDesc) {
if ( [finPeriod.EndDate compare:date] == NSOrderedAscending ){ // finPeriod.EndDate < date
lastPeriod = finPeriod;
break;
}
}
return lastPeriod;
}
However, when replacing the first lines (lazy instantiation) in the method by removing the if clause and always instantiating and sorting NSArray sortedFinPeriodsDesc, the code works fine.
Hence, I have a couple of questions:
- What is the error in my code? How does affect lazy instantiation
faulting? - Would you recommend defining the NSArray
sortedFinPeriodsDescas transient attribute and sorting it inawakeFromFetchinstead? - What would be the best option in your view?
Thank you very much for your help!
The “lazy loading” smacks of a premature optimisation. Particularly the way you’ve implemented it, you aren’t actually using an instance variable, but a global variable (see here for details), meaning that each object isn’t holding its own version of the array.
I would suggest having the array local and generating it each time it is required. If this impacts performance, you can look at other methods, but even with the ivar problem above resolved, you are going to hit problems if the periods set is updated – your array is now out of date.
You haven’t said how many times your objects are being asked for this period, or how many objects, or how many periods, so it is difficult to give more specific advice.
A fetched property might be a more efficient way of getting the period, but I don’t have enough experience with them to help in your specific case.