核心数据:使用延迟实例化时出现奇怪的错误行为

时间:2012-07-24 09:27:58

标签: objective-c ios ios5 core-data nsmanagedobject

我已经在我的NSManagedObject IBCompany中添加了一个类别,该类别应根据简单的日期比较检索特定时间段,这是IBCompany的关系之一。

当我运行以下代码时,NSArray sortedFinPeriodsDesc以正确的排序顺序包含故障时段。但是,在for each循环中访问它们时,每个句点的属性都返回nil,特别是其EndDate的nil。出于这个原因,我的方法lastReportedPeriodforDate总是返回nil,这是一个错误。

#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;
}

但是,当通过删除if clause替换方法中的第一行(延迟实例化)并始终实例化和排序NSArray sortedFinPeriodsDesc时,代码工作正常。

因此,我有几个问题

  • 我的代码中有什么错误?如何影响延迟实例化 断层?
  • 您是否建议将NSArray sortedFinPeriodsDesc定义为瞬态属性并在awakeFromFetch中对其进行排序?
  • 您认为最好的选择是什么?

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

“延迟加载”带来了过早的优化。特别是你实现它的方式,你实际上并没有使用实例变量,而是使用全局变量(详见here),这意味着每个对象都没有拥有自己的数组版本。

我建议将数组放在本地并在每次需要时生成它。如果这会影响性能,您可以查看其他方法,但即使上面解决了ivar问题,如果更新了句点设置,您将遇到问题 - 您的阵列现在已过期。

您还没有说过在此期间要求对象的次数,或者有多少个对象,或者有多少个时段,因此很难提供更具体的建议。

fetched property可能是获得这段时间的更有效方式,但我没有足够的经验来帮助您完成特定情况。