ежемесячное обновление объектов coredata - PullRequest
0 голосов
/ 31 марта 2012

в текущем проекте я управляю объектами Month, которые содержат информацию о прошедшем месяце, и один из них, конечно, обозначает текущий месяц.

каждый месяц содержит атрибут number, который действует какидентификатор года.атрибут содержит NSNumber of type int32, который идентифицирует месяц в формате: YYYYMM.так, например, февраль 2011 года имеет атрибут number = 201102.

в приложении, в которое пользователь вводит данные, которые всегда связаны с текущим месяцем.у пользователя нет возможности редактировать, удалять или добавлять данные за прошедший месяц.

, поэтому мои coredata содержат 1 month для текущего месяца, который будет обновлен, и столько же объектов, сколько в месяцепрошло, в котором пользователь ввел данные.

у меня есть функция

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

в моем классе DAO, которая создает новый объект month в coredata или обновляет текущий месяц, еслипрошло NSNumber соответствует текущему месяцу.

здесь идет сложная часть

каждый раз, когда пользователь открывает приложение впервые в новом месяце, мне нужно приложениеархивировать все passed month, которые еще не имеют соответствующего объекта core-data.

как я это сделал до сих пор (для целей тестирования) выглядит так:

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

У меня есть этона моем заводе, который вызывается при запуске приложения.

Вопросы Это очень уродливо и создает много накладных расходов

  • Как можноя определяю, если это первый раз вмесяц, когда пользователь открывает приложение, поэтому мне не нужно архивировать каждый раз, когда он запускает приложение?
  • Кто-нибудь из вас видит лучший способ перебирать прошедший месяц?
  • может даже бытькаким способом мне не нужно выбирать каждый месяц, чтобы определить, существует ли он уже?
  • Могу ли я как-нибудь выяснить, что было заархивировано в прошлом месяце, и начать оттуда итерацию?

Я был бы очень признателен за помощь, заранее спасибо =) если вам нужно больше кода, или вы можете найти что-то, что может отсутствовать в вопросе, я буду рад предоставить его.

note thisкод макета, который я использовал для тестирования, вопрос не в том, как улучшить код, а в том, как улучшить алгоритм =)

1 Ответ

2 голосов
/ 03 апреля 2012

Я бы сделал это так:

  1. Запустите ваш ежемесячный чек и сохраните значение yyyyMM в NSUserDefaults.
  2. При каждом запуске приложения рассчитывается значение yyyyMM для текущей даты и сравнивается со значением, хранящимся в NSUserDefaults.
  3. Если он не совпадает, значит, это новый месяц, поэтому повторите ежемесячные проверки.

Это выглядит так:

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

Это просто добавляет 87 к числу, когда оно достигает 13, чтобы изменить что-то вроде 201113 на 201201

...