2013-10-11 4 views
1

Я определил основные данные для моего проекта и реализовал атрибут ENtity: isRealEntry.Как настроить сохранение в основных данных?

@interface FTRecord : NSManagedObject 

@property (nonatomic) NSTimeInterval lastUpdated; 
@property (nonatomic) BOOL isRealEntry; 

@end 

Теперь, когда я сохранить контекст (NSManagedObjectContext *context;)

NSError *error = nil; 
BOOL successful = [context save:&error]; 

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

Как я могу это достичь?

Update:

Сначала я нашел решение Мартина очень многообещающим. Однако я получаю очень неприятный побочный эффект, когда я сохранить данные при входе в фоновом режиме:

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    [[FTRecordStore sharedStore] saveChanges]; 
} 

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    FTRecord *record = [[[FTRecordStore sharedStore] getAllRecords] objectAtIndex:[indexPath row]]; 

FTRecordCellView *cell = [tableView dequeueReusableCellWithIdentifier:@"FTRecordCellView"]; 

    [[cell notesLabel] setText:[record notes]]; 

return cell; 
} 

Я не уверен, как это решить. Мой магазин - одноэлементный. getAllRecords определяет содержимое выше для каждой ячейки. Следовательно, мне нужно иметь то же значение для getAllRecords, что и в tableView, иначе он сработает.

Другое предлагаемое решение с двумя источниками одного в памяти и в db также не представляется возможным, как я могу подавать один TableView с двумя источниками?

Update 2:

Я имел обидное упущение. Недостаточно удалить запись из контекста. Мне также пришлось удалить его из массива.

[allRecords removeObjectIdenticalTo:record]; 

Поэтому я забираю его обратно. Решение Мартина отлично работает. Однако мне все же интересно узнать, может ли UITableView действительно быть из двух источников (db/memory), как это предлагается в другом решении. Спасибо

ответ

0

Сохранение контекстов управляемого объекта сохраняет все изменений в этом контексте. Вы не можете исключить некоторые объекты из операции сохранения.

Чтобы отменить все изменения в «нереальные» объекты, вы могли бы реализовать метод NSManagedObject подкласса willSave :

- (void)willSave 
{ 
    if (![self.isRealEntry boolValue]) { 
     if (self.isInserted) { 
      // Object was inserted, remove it again: 
      [self.managedObjectContext deleteObject:self]; 
     } else if (self.isUpdated) { 
      // Object was modified, undo all changes: 
      [self.managedObjectContext refreshObject:self mergeChanges:NO]; 
     } 
    } 
} 

(я никогда не делал это в реальном проекте, но я построил небольшой тест приложение и похоже работать.)

+0

Извините, Мартин, как вы предупреждали, вызвал некоторые проблемы, которые я дал в своем обновлении. Есть ли у вас другая идея относительно UITableView, использующего два источника (память/db)? – Houman

+0

@Kave: посмотрите http://stackoverflow.com/questions/14004055/how-to-use-core-data-models-without-saving-them/14005159#14005159. Это похоже на предложение Дункана, но использует только один контекст управляемого объекта с двумя магазинами: «реальные» объекты назначаются хранилищу SQLite, а «нереальные» объекты назначаются хранилищу памяти. –

0

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

2

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

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

Вы можете создать в Memeory постоянный магазин координатор вроде этого:

inMemoryPersistentStoreCoordinator = [[NSPersistentStoreCoordinator Alloc] initWithManagedObjectModel: [само managedObjectModel]];

[inMemoryPersistentStoreCoordinator addPersistentStoreWithType: NSInMemoryStoreType configuration: nil URL: nil options: nil error: & error];

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

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

+1

+1. Вы даже можете использовать * one * context, * one * persistent store Coordinator и * two * stores (sqlite + в памяти), а затем ассоциировать объекты с одним хранилищем или другим: http://stackoverflow.com/a/14005159/1187415. - Очевидно, я забыл свой собственный ответ год назад :-) –

+0

Спасибо, Мартин, приятное дополнение! Я не знал, что вы могли бы это сделать – Duncan

+0

Хотя это верное решение, я считаю, что другое решение Мартина, которое я принял в качестве ответа, менее сложно. Переопределение «WillSave» намного более возможно, чем управление двумя наборами хранилищ. :) – Houman

Смежные вопросы