每月更新核心数据对象

时间:2012-03-31 13:29:15

标签: objective-c ios core-data

在当前项目中,我管理的实体Month包含有关已过期月份的信息,其中一个当然代表当月。

每个月都包含一个number属性,该属性充当年份的标识符。该属性包含NSNumber of type int32,用于标识格式为YYYYMM的月份。例如,2011年2月具有属性number = 201102

在用户输入数据的应用程序中,该数据总是受当前月份的影响。用户无法编辑,删除或添加过月的月份数据。

所以我的coredata保留了1 month,用于当前月份的更新,以及用户输入数据的月份已经过去的许多其他对象。

我有一个功能

-(void)archiveMonth:(NSNumber *)month;

在我的DAO类中,它在coredata中创建一个新的month对象,或者如果传递的NSNumber与当前月份匹配,则更新当前月份。

这里有棘手的部分

每次用户在新的月份第一次打开应用程序时,我都需要应用程序归档所有没有相应核心数据对象的passed month

到目前为止我是如何做到的(出于测试目的)看起来像这样:

    NSDate *rootDate = [NSDate dateWithTimeIntervalSinceReferenceDate:(10*365*24*60*60)];
    // somewhere in 2010 so to be sure to catch all passed month

    NSNumber *rootMonth = [dataHandler getMonthNumber:rootDate] ;
    NSNumber *iterator;   // acts as the monthnumber currently active in the loop
    int now = [dataHandler getMonthNumber:[NSDate date]].intValue;

    iterator = [NSNumber numberWithInt:rootMonth.intValue];
    while (now >= iterator.intValue) {
        iterator = [NSNumber numberWithInt:iterator.intValue+1];
        if (iterator.intValue%100 > 12) { //jump all invalid month numbers 

            while (iterator.intValue%100 != 1) {
                iterator = [NSNumber numberWithInt:iterator.intValue+1 ];
            }
        }

        NSArray *temp = [dataHandler fetchMonth:iterator];
        if (temp.count == 0) {                         
            //  no data = needs archive
            [dataHandler archiveMonth:iterator];
        }
    }

我在我的工厂里有这个在应用程序启动时被调用。

问题 这非常难看并且会产生大量开销

  • 如何确定用户是否在本月第一次打开应用程序,这样我每次启动应用程序时都不需要存档?
  • 你们中的任何一个人看到了更好的方法来迭代过去一个月吗?
  • 可能甚至有一种方法我每个月都不需要取出来确定它是否已经存在?
  • 我可以以某种方式找出上个月存档的内容,并从那里开始迭代吗?

我真的很感激一些帮助,在此先感谢=) 如果您需要更多代码,或者在问题中找不到某些内容,请尽快提供。

注意这是一个模型代码,我用于测试,问题不是如何改进代码,而是如何改进算法=)

1 个答案:

答案 0 :(得分:2)

我会这样做:

  1. 运行每月检查并将yyyyMM值存储到NSUserDefaults
  2. 每次启动应用程序,计算当前日期的yyyyMM值,并将其与NSUserDefaults中存储的值进行比较。
  3. 如果不匹配,则为新月,请再次运行每月检查。
  4. 看起来像这样:

    #define KEY_FOR_MONTHLY_LAST_CHECKED @"monthlyCheckedKey"
    
    - (NSInteger)yyyyMMFromDate:(NSDate *)date {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"yyyyMM"];
    
        NSString *yyyyMMString = [formatter stringFromDate:date];
        return [yyyyMMString intValue];
    }
    
    - (void)runMonthly {
        // This code is run once per month
    
        // Update NSUserDefaults
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setInteger:[self yyyyMMFromDate:[NSDate date]] forKey:KEY_FOR_MONTHLY_LAST_CHECKED];
        [defaults synchronize];
    }
    
    - (void)checkMonthly {
        NSUserDefaults *defaults    = [NSUserDefaults standardUserDefaults];
        NSInteger lastCheckedyyyyMM = [defaults integerForKey:KEY_FOR_MONTHLY_LAST_CHECKED];
        NSInteger currentyyyyMM     = [self yyyyMMFromDate:[NSDate date]];
    
        if (lastCheckedyyyyMM != currentyyyyMM) {
            [self runMonthly];
        }
    }
    

    您只需添加[self checkMonthly];即可在每次启动应用程序时运行。

    另外,我会改变这个:

    if (iterator.intValue%100 > 12) { //jump all invalid month numbers 
        while (iterator.intValue%100 != 1) {
            iterator = [NSNumber numberWithInt:iterator.intValue+1 ];
        }
    }
    

    对此:

    if (iterator.intValue % 100 == 13) { //jump all invalid month numbers 
        iterator = [NSNumber numberWithInt:iterator.intValue+88];
    }
    

    当它达到13时将数字增加87,以便将201113更改为201201