NSFetchedResultsController со многими NSSortDescriptor

в моем приложении я сортирую объект, используя только один NSSortDescriptor, но теперь мне нужно отфильтровать данные по 4 различным атрибутам. Это код для текущей сортировки, результатом являются все записи объекта, отсортированные по атрибуту displayOrder, но мне нужно отфильтровать записи по четырем другим атрибутам (год, месяц, день, группа), все они целочисленные32 кроме группы, которая является строкой:

- (NSFetchedResultsController *)fetchedResultsController
{
  if (fetchedResultsController) return fetchedResultsController;

  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  NSEntityDescription *entity = 
               [NSEntityDescription entityForName:@"FavoriteThing" 
                           inManagedObjectContext:managedObjectContext];

  [fetchRequest setEntity:entity];

  NSSortDescriptor *sortDescriptor = 
              [[NSSortDescriptor alloc] initWithKey:@"displayOrder" 
                                          ascending:YES];

  NSArray *sortDescriptors = [[NSArray alloc] 
                              initWithObjects:sortDescriptor, nil];  
  [fetchRequest setSortDescriptors:sortDescriptors];

  NSFetchedResultsController *aFetchedResultsController = 
              [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                  managedObjectContext:managedObjectContext
                                                    sectionNameKeyPath:nil cacheName:@"ThingsCache"];
  aFetchedResultsController.delegate = self;
  [self setFetchedResultsController:aFetchedResultsController];

  [aFetchedResultsController release];
  [fetchRequest release];
  [sortDescriptor release];
  [sortDescriptors release];

  return fetchedResultsController;
}    

Я попытался добавить предикат:

NSNumber *yearSearched = 1965;
NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:@"todoYear = %@", yearSearched];

[fetchRequest setPredicate:yearPredicate];

Но после запуска приложения появляется ошибка EXC_BAD_ACCESS в строке NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:@"todoYear = %@", yearSearched];

Где атрибут todoYear имеет тип Integer32


person mvasco    schedule 12.12.2013    source источник
comment
Что вы имеете в виду под фильтром и что вы пробовали?   -  person Wain    schedule 12.12.2013
comment
Спасибо за ответ @Wain, я имею в виду фильтрацию записей, соответствующих некоторым условиям (год = x, месяц = ​​y, день = z, группа = @Azul)...   -  person mvasco    schedule 12.12.2013
comment
Таким образом, вы должны добавить предикат, а не другой дескриптор сортировки.   -  person Wain    schedule 12.12.2013
comment
Хорошо, я только что загрузил PDF-файл Apple NSPredicate Class Reference, я попытаюсь найти способ реализовать свои потребности. В любом случае, спасибо.   -  person mvasco    schedule 12.12.2013
comment
Привет еще раз, я включил следующие строки, чтобы проверить это: NSNumber *yearSearched = 1965; NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:@todoYear = %@, yearSearched]; [fetchRequest setPredicate:yearPredicate]; Но после запуска приложения возникает ошибка EXC_BAD_ACCESS в строке NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:@todoYear = %@, yearSearched]; [fetchRequest setPredicate:yearPredicate]; Атрибут todoYear относится к типу Integer32. Спасибо @Wain   -  person mvasco    schedule 13.12.2013
comment
Вы должны добавить сведения об исключении, если вы получаете исключения...   -  person Wain    schedule 13.12.2013


Ответы (1)


Ваше создание NSNumber неверно (вы просто устанавливаете указатель на целое число). Так должно быть:

NSNumber *yearSearched = @1965;
NSPredicate *yearPredicate = [NSPredicate predicateWithFormat:@"todoYear = %@", yearSearched];

[fetchRequest setPredicate:yearPredicate];
person Wain    schedule 12.12.2013
comment
Еще раз спасибо @Wain, обновление кода с вашим последним ответом не вызывает исключений, но приложение продолжает показывать все строки, а не ожидаемые строки, есть только одна запись со значением 1965 в атрибуте «todoYear»... - person mvasco; 13.12.2013
comment
Вы когда-нибудь звонили performFetch: по FRC? - person Wain; 13.12.2013
comment
Обычно вы вызываете его перед возвратом нового FRC (при его создании). - person Wain; 13.12.2013
comment
Я обновил ваш ответ своим полным исходным кодом, так что вы можете проверить, что там не так. - person mvasco; 13.12.2013
comment
Хорошо, переместите PerformFetch: в аксессор и удалите кеш из FRC (вы должны удалить кеш, если вы меняете запрос на выборку). - person Wain; 13.12.2013
comment
Извините @Wain, я еще не эксперт, не могли бы вы объяснить, что делать? - person mvasco; 13.12.2013
comment
давайте продолжим это обсуждение в чате - person Wain; 13.12.2013
comment
Еще раз привет, я включил следующую строку [NSFetchedResultsController deleteCacheWithName:@ThingsCache]; и после сброса симулятора iOS приложение работает нормально, предикат фильтрует данные и таблица показывает ожидаемые данные. Но после запуска приложения во второй раз выдается исключение. Я помещу текст исключения в ваш ответ. - person mvasco; 13.12.2013
comment
Просто удалите имя кеша. - person Wain; 13.12.2013
comment
Как вы думаете, это нормально, что приложение нормально работает на реальном устройстве, и когда я запускаю его во второй раз на симуляторе iOS, оно зависает, выдавая исключение??? - person mvasco; 13.12.2013
comment
Он выдает исключение, когда вы не уничтожили кеш, но изменили запрос на выборку. Вы можете сделать это на устройстве, если установите и запустите приложение, а затем измените код и снова запустите... - person Wain; 13.12.2013
comment
Спасибо @Wain, но что мне делать, чтобы избежать этой проблемы? Я не хочу иметь нестабильное приложение... - person mvasco; 13.12.2013
comment
Не используйте кеш, если вы собираетесь изменить запрос на выборку (это то, что говорится в документации). Или удалите кеш при изменении запроса на выборку. - person Wain; 13.12.2013
comment
Честно говоря, я точно не знаю, для чего нужен кеш, я обновил код своего приложения из учебника и шаг за шагом разрабатываю приложение, добавляя новые функции и учась у таких людей, как вы, но я попытался удалить кеш и приложение вылетает. Не будете ли вы так любезны и обновите мой код так, чтобы кеш больше не был нужен? - person mvasco; 13.12.2013
comment
Я установил имя кеша как nil, и приложение больше не падает, спасибо @Wain - person mvasco; 13.12.2013