Как эффективно сбросить атрибуты в основном объекте данных - PullRequest
0 голосов
/ 31 октября 2011

Мое приложение использует Базовые данные и имеет атрибут с именем 'beenSeen'. Когда пользователь обновляет приложение, все значения «beenSeen», равные 1, изменяются на 0. На iPod Touch 2-го поколения с более чем 2000 объектами обновление занимает более минуты. Мой код выглядит так:

    for (Deck *deck in self.deckArray) {
        if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
            [deck setBeenSeen:[NSNumber numberWithInt:0]];
            [self.managedObjectContext save:&error];           
        }
    }

Я также рассматриваю возможность удаления файла sqlite и выдачи предупреждения, чтобы пользователь сам перезапустил приложение. Делать это наверняка намного быстрее, чем сейчас. Есть ли более быстрый способ обновить сущность? Могу ли я иметь «резервную» сущность и скопировать ее? Спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 31 октября 2011

Попробуйте, во-первых, отфильтруйте массив, используя предикат:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"beenSeen == %@", 
                          [NSNumber numberWithInt:1]];

NSArray* filtered = [self.deckArray filteredArrayUsingPredicate:predicate];

Теперь установите новое значение:

[filtered setValue:[NSNumber numberWithInt:0] forKeyPath:@"beenSeen"];

Наконец сохраните контекст:

[self.managedObjectContext save:&error];

Надеюсь, это поможет:)

1 голос
/ 31 октября 2011

Hm. Первая оптимизация, которую я бы предложил, была бы

for (Deck *deck in self.deckArray) {
    if ([deck.beenSeen isEqualToNumber:[NSNumber numberWithInt:1]]) {
        [deck setBeenSeen:[NSNumber numberWithInt:0]];
    }
}
[self.managedObjectContext save:&error];           

Я подозреваю, что это может ускорить выполнение одного большого сохранения контекста вместо 2000 маленьких.

Вторым предложением будет попытка избавиться от теста if - если большинство ваших значений beenSeen изменяются с 1 на 0, а остальные уже равны 0, то вы можете просто установить все из них до 0 и сэкономить время проверки каждого в отдельности. (С другой стороны, если имеется 10 000 объектов, а вы сбрасываете 2000 из них, то избавление от теста может быть неоптимальным.)

for (Deck *deck in self.deckArray) {
    [deck setBeenSeen:[NSNumber numberWithInt:0]];
    }
    [self.managedObjectContext save:&error];           
}

Третьим предложением было бы подумать о реализации этого другого способа - например, ваш объект колоды мог бы реализовать атрибут lastSeen, сохраняя дату и время, когда колоду видели в последний раз, а затем вместо массового сброса (и записывая 2000 строк базовых данных), вы можете просто проверить дату и время каждой колоды lastSeen с отметкой времени последнего обновления пользователя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...