NSFetchedResultsController создает дополнительные пустые строки при использовании предиката "! =" - PullRequest
0 голосов
/ 26 марта 2011

У меня есть UITableViewController, который заполняется NSFetchedResultsController.Моя сущность CoreData имеет атрибут «submitter_id».В зависимости от того, как инициализирован мой контроллер, я хочу получить записи, которые соответствуют заданному submitter_id или которые не соответствуют указанному submitter_id.Дело "соответствует" работает нормально, но у меня проблемы с делом "не соответствует".Моя база данных sqlite верна, но я получаю дополнительные пустые строки в TableView.

В следующем выводе я получаю правильные 3 записи из Core Data, но затем NSFetchedResultsController (или кто-то еще) добавляет еще 34 пустых строкик моему TableView.Примечание: количество пустых строк следует шаблону, который может быть подсказкой: если я удаляю приложение и начинаю с нуля, я сначала получаю 17 пустых строк + 3 хороших.Когда я запускаю его второй раз, я получаю 34 пустых строки + 3 хороших.С тех пор он стабилен на 34 пустых рядах.Интересно, что в моем тестовом наборе данных 17 записей.

2011-03-25 15:35:17.256 test[54095:207] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZDELETED, t0.ZDESCRIPTION, t0.ZITEMID, t0.ZICON, t0.ZAVG, t0.ZNAME, t0.ZCREATIONDATE, t0.ZIMAGE, t0.ZSUBMITTERID, t0.ZUSER FROM ZITEM t0 WHERE  t0.ZSUBMITTERID <> ? ORDER BY t0.ZNAME DESC
2011-03-25 15:35:17.257 test[54095:207] CoreData: details: SQLite bind[0] = 32
2011-03-25 15:35:17.258 test[54095:207] CoreData: annotation: sql connection fetch time: 0.0017s
2011-03-25 15:35:17.258 test[54095:207] CoreData: annotation: fetch using <NSSQLiteStatement: 0x5f920f0> returned 3 rows with values: (
    "Plastic ballpoint",
    "Walmart readers",
    Blue
)
2011-03-25 15:35:17.263 test[54095:207] CoreData: annotation: total fetch execution time: 0.0071s for 3 rows.
2011-03-25 15:35:17.264 test[54095:207] numberOfSectionsInTableView: 1
2011-03-25 15:35:17.264 test[54095:207] numberOfRowsInSection 0: 37
2011-03-25 15:35:17.265 test[54095:207] indexPath 0
2011-03-25 15:35:17.268 test[54095:207] name: pen
2011-03-25 15:35:17.268 test[54095:207] indexPath 1
2011-03-25 15:35:17.269 test[54095:207] name: glasses
2011-03-25 15:35:17.269 test[54095:207] indexPath 2
2011-03-25 15:35:17.270 test[54095:207] name: checkbook
2011-03-25 15:35:17.270 test[54095:207] indexPath 3
2011-03-25 15:35:17.272 test[54095:207] name: (null)
2011-03-25 15:35:17.273 test[54095:207] indexPath 4
2011-03-25 15:35:17.275 test[54095:207] name: (null)
2011-03-25 15:35:17.275 test[54095:207] indexPath 5
2011-03-25 15:35:17.275 test[54095:207] name: (null)
2011-03-25 15:35:17.278 test[54095:207] indexPath 6
2011-03-25 15:35:17.279 test[54095:207] name: (null)
2011-03-25 15:35:17.279 test[54095:207] indexPath 7
2011-03-25 15:35:17.280 test[54095:207] name: (null)
2011-03-25 15:35:17.281 test[54095:207] indexPath 8
2011-03-25 15:35:17.281 test[54095:207] name: (null)

Вот код, в котором я настроил NSFetchedResultsController:

   - (BOOL) setupFRC
    {
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        request.entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
        request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:NO]];

        NSPredicate *p1;
        if (self.listType == MY_ITEMS_LIST) {
            p1 = [NSPredicate predicateWithFormat:@"submitterID == %qu", appDelegate.user.userID];
        }
        else {
            p1 = [NSPredicate predicateWithFormat:@"submitterID != %qu", appDelegate.user.userID];
        }
        request.predicate = p1;

        NSFetchedResultsController *frc = [[NSFetchedResultsController alloc]
                                           initWithFetchRequest:request
                                           managedObjectContext:self.managedObjectContext
                                           sectionNameKeyPath:nil
                                           cacheName:nil];
        frc.delegate = self;

        self.fetchedResultsController = frc;
        [frc release];
        [request release];

        return YES;
    }

    - (void)performFetchForTableView
    {
        NSError *error = nil;
        [self.fetchedResultsController performFetch:&error];
        if (error) {
            NSLog(@"[CoreDataTableViewController performFetchForTableView:] %@ (%@)", [error localizedDescription], [error localizedFailureReason]);
        }
        [self.tableView reloadData];
    }

А вот где я форматирую ячейки:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForManagedObject:(NSManagedObject *)managedObject
{
    static NSString *CellIdentifier;
    if (self.listType == MY_ITEMS_LIST) {
        CellIdentifier = @"RSMyItemCell";
    }
    else {
        CellIdentifier = @"RSTBDItemCell";
    }

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    CDItem *item = (CDItem *)managedObject;
    cell.textLabel.text = item.name;
    cell.detailTextLabel.text = item.description;
    NSLog(@"name: %@",item.name);
    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    NSInteger n = [sectionInfo numberOfObjects];
    NSLog(@"numberOfRowsInSection %d: %d",section,n);
    return n;
}

Я уверен, что что-то упустил, но я озадачен тем, как отлаживать это дальше.Кто-нибудь видел это раньше?Если вы хотите увидеть другие фрагменты кода, дайте мне знать.

Спасибо!

stu

1 Ответ

0 голосов
/ 28 марта 2011

Иногда ясная голова - это все, что нужно. Возвращаясь после выходных, я увидел проблему. Для справки вот что произошло:

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

[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]

перед выполнением проверки моего существования. Это привело к созданию объекта без соответствующего управляемого объекта. Даже если CoreData возвращает правильный набор данных в NSFetchedResultsController, контроллер должен использовать счетчик сущностей для определения [sectionInfo numberOfObjects];

В любом случае, перемещение вызова insertNewObjectForEntityForName внутри предложения «не существует» (где происходит addObject) решило проблему.

Спасибо

сту

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