2013-02-15 5 views
2

Я искал и до сих пор не нашел ничего, что вполне работает. Либо вопрос/ответ слишком старый, либо просто не работал для меня. Это моя первая попытка «моего» приложения. Поскольку это кажется правом перехода, я делаю приложение контрольного списка. Вот что я ищу:Основные данные iOS - обновление нескольких записей

Моих хранилищ данных содержат 4 атрибутов: name, category, isChecked, isActive (непременно будет следовать, как я расширяю)

Когда мой View Controller первоначально нагрузка, то NSFetchedResultsController имеет NSPredicate, что только извлекает запись чей атрибут isActive есть ДА (или [NSNumber numberWithBool:YES). Затем он берет эти записи и отображает их в соответствующие ячейки для пользователя. Когда пользователь нажимает на ячейку, хранилище данных обновляет и соответственно изменяет атрибут isChecked. Все работает хорошо.

Что мне нужно сделать сейчас, так это удалить элементы (1 или более) из списка. В частности, мне нужно обновить атрибуты хранилища данных isChecked и isActive до НЕТ, только если это текущее значение isChecked - это ДА. (Я не ищу, чтобы удалить запись из хранилища данных, поскольку они будут использованы для создания базы данных для пользователей будущего использования.)

Я использовал, среди прочего:

[[[self fetchedResultsController] fetchedObjects] 
    setValue:[NSNumber numberWithBool:NO] 
    forKey:@"isChecked"]; 

Это действительно работает, оно удаляет галочку (флажки) и соответственно обновляет хранилище. Проблема заключается не только в том, что я делаю еще один запрос в хранилище данных для элементов isActive, он также выполняет поиск по всему «активному списку», который был извлечен, и присваивает каждому из своих атрибутов isChecked значение «НЕТ». Это может быть не слишком большой проблемой для небольших списков, но поскольку список (и) расширяется, это может быть проблемой.

Другая проблема, если я добавлю: (., А также второй запрос хранилища данных в пределах одного метода)

[[[self fetchedResultsController] fetchedObjects] 
    setValue:[NSNumber numberWithBool:NO] 
    forKey:@"isActive"]; 

Он устанавливает все мои элементы списка до NO

Так мой вопрос: как я могу пройти через список, найти только те элементы, которые отмечены, и обновлять только те записи (установить как isChecked & & isActive attributes = NO), чей атрибут isChecked является ДА, а не работает через весь список?

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

Любая помощь будет принята с благодарностью. Спасибо заранее и, пожалуйста, будьте осторожны: -].

EDIT

Я попытался с помощью for петлю, for (NSString *item in fetchedResultsController), но я получаю ошибку ...may not respond to 'countByEnumeratingWithState:objects:count'

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

Edit 2

Вот оригинал ошибки я получил, когда я запустил вторую отдельную fetchRequestController для этой кнопки/метод:

An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 3 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

ответ

2

Вы можете просто цикл по коллекции fetchedObjects и изменить управляемые объекты. После их изменения вам нужно будет перезагрузить свой список (думаю, вы используете tableview).

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

NSArray* myCollection = [[self fetchedResultsController] fetchedObjects]; 
for(ActiveListData *managedObject in myCollection) 
{ 
    if(managedObject != nil && managedObject.isChecked) 
    { 
     managedObject.isChecked = NO; 
     managedObject.isActive = NO; 
    } 
} 

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

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

Edit: Если вы не знакомы с использованием основных данных в документации яблока предоставляет много информации: http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/Articles/cdBasics.html

+0

Я попробовал это, используя 'ActiveListData' который является именем моего NSManaged подкласса, но получил ошибка «Исключение было обнаружено во время обработки изменений Core Data. Обычно это ошибка в наблюдателе NSManagedObjectContextObjecsDidChangeNotification. нет объекта в индексе 3 в разделе с индексом 0 с userInfo (null). Проверьте мое редактирование выше для исходной ошибки, которую я получил для создания отдельного «fetchRequestController» для этого. –

+0

Да, я заглянул в яблоко dev docs, и есть TON информации, но для того, чтобы найти реальный пример (если когда-либо есть пример), вам нужно найти множество примеров. По крайней мере, здесь я могу поставить то, что мне нужно, в контекст и получить относительно прямой ответ. Я прочитал dev docs, что я могу, но это не всегда самое простое место для ответа –

+0

Что возвращает fetchedObjects? Это NSArray? – ggfela

1

Благодаря @ggfela для своего ответа. Процессы его ответа были на месте. Вот фактический код, который я положил в мою кнопку/метод, в надежде на него, помогая кому-то еще в будущем:

NSArray *moc = [[self fetchedResultsController] fetchedObjects]; 

for (ActiveListData *item in moc) { 
    if (item != nil && item.isChecked.boolValue == 1) { 
     item.isChecked = [NSNumber numberWithBool:NO]; 
     item.isActive = [NSNumber numberWithBool:NO]; 
    } 
} 

// Call to Data Store to update the list 
NSError *error; 
if (![self.managedObjectContext save:&error]) { 
    FATAL_CORE_DATA_ERROR(error); 
    return; 

Объяснение:

Загрузите содержимое результата от вызова метода fetchedResultsController во временную переменную с именем moc

Используйте цикл for для циклического перемещения по массиву moc. ActiveListData - это подкласс NSManagedObject, который я создал для своих основных данных, и является подходящим местом для вставки разделенных значений/атрибутов из хранилища данных. Оттуда это довольно просто, я гарантирую, что item не nil И что атрибут элемента - это значение, которое мне нужно.

ПРИМЕЧАНИЕ

основных данных не хранит значения BOOL ДА и НЕТ, но скорее 1 и 0, соответственно, но при вызове или сравнить значения, вы просто не можете сравнить стоимость item.isChecked, потому что это передается вам как bool, а не как целое число. Вы не можете просто сравнить item.isChecked == YES либо с @propertyisChecked - это NSNumber. Итак, в случае if я положил item.isChecked.boolValue, так как это даст мне представляющее целое число для его значения bool, в этом случае у меня есть проверка на 1 (ДА). (Извините, если мое объяснение неверно и/или запутывает, но это то, как я это понимаю, и это единственный способ, которым этот код работает.)

Затем установка новых значений этих атрибутов такова, как вы ожидали при настройке любых другая переменная.Единственное «хитрым» разница с этим является то, что подкласс NSManagedObject устанавливает @property в isChecked и isActive к NSNumber (как упоминалось ранее), поэтому для того, чтобы отправить соответствующие значения обратно в основных данных используется метод numberWithBool из NSNumber класса ,

И на всякий случай кто-то путается моим звонком FATAL_CORE_DATA_ERROR(error), это просто макрос, который был определен внутри файла Prefix.pch для обработки моих ошибок из управляемого объекта управления. Вы можете использовать любую (или никакую) обработку ошибок, которую вы выберете.

Еще раз спасибо @ggfela за помощь! Если у кого-то еще есть какие-то другие предложения о том, как этот код следует применять, пожалуйста, дайте мне знать!

+0

Хорошая работа, я полностью забыл, что CoreData использует NSNumbers вместо booleans. – ggfela

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