1

想象一下新聞應用程序。該應用程序有多個頻道,每個頻道有x個新聞。 第一個ViewController是一個UITableViewController,它將所有通道顯示爲剖面和最大值。每條頻道/部分有3條新聞。iOS CoreData/NSFetchedResultsController:將結果限制爲每個部分3個

我使用NSFetchedResultsController。我怎樣才能實現NSFetchedResultsController獲取每節3新聞?

將NSFetchRequest中的fetchLimit設置爲3會將整個結果限制爲3(= 1節包含3行)。

任何想法?

編輯

目前我使用此代碼:
UITableViewDataSource東西(NUMBER_OF_ITEMS_PER_CHANNEL = 3):

- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView 
{ 
    return [self.fetchedResultsController.sections count]; 
} 

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    id<NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section]; 
    NSInteger numberOfRows = [sectionInfo numberOfObjects]; 
    if (numberOfRows > NUMBER_OF_ITEMS_PER_CHANNEL) { 
     numberOfRows = NUMBER_OF_ITEMS_PER_CHANNEL; 
    } 
    return numberOfRows; 

} 

NSFetchedResultsControllerDelegate東西:

- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller 
{ 
    [self.tableView beginUpdates]; 
} 

- (void)controller:(NSFetchedResultsController*)controller 
    didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo 
      atIndex:(NSUInteger)sectionIndex 
     forChangeType:(NSFetchedResultsChangeType)type 
{ 
    UITableView* tableView = self.tableView; 

    switch (type) { 
    case NSFetchedResultsChangeInsert: 
     [tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    default: 
     break; 
    } 
} 

- (void)controller:(NSFetchedResultsController*)controller 
    didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath*)theIndexPath 
     forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath*)newIndexPath 
{ 
    UITableView* tableView = self.tableView; 

    switch (type) { 
    case NSFetchedResultsChangeInsert: 
     if (newIndexPath.row < NUMBER_OF_ITEMS_PER_CHANNEL) { 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      id<NSFetchedResultsSectionInfo> sectionInfo = [controller sections][newIndexPath.section]; 
      NSInteger numberOfRowsInSection = [sectionInfo numberOfObjects]; 
      if (numberOfRowsInSection > NUMBER_OF_ITEMS_PER_CHANNEL) { 
       [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:NUMBER_OF_ITEMS_PER_CHANNEL inSection:newIndexPath.section]] withRowAnimation:UITableViewRowAnimationFade]; 
      } 
     } 
     break; 

    case NSFetchedResultsChangeDelete: 
     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:theIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeUpdate: 
     [self fetchedResultsController:controller configureCell:[tableView cellForRowAtIndexPath:theIndexPath] atIndexPath:theIndexPath]; 
     break; 

    case NSFetchedResultsChangeMove: 
     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:theIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    } 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller 
{ 
    [self.tableView endUpdates]; 
} 

但是,當有新的消息可(控制器:didChangeObject ....被稱爲與type = NSFetchedResultsChangeInsert)我得到的錯誤是這樣的:

CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 3. The number of rows contained in an existing section after the update (3) must be equal to the number of rows contained in that section before the update (3), 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)

任何想法如何避免這個錯誤?

+0

我認爲在這種情況下,您需要獲取新聞實體本身,而不是頻道實體,但使用NSPredicate。所以基本上就像'NSPredicate * predicate = [NSPredicate predicateWithFormat: @「channel ==%@」,channelName];如果你不知道有多少個頻道,那麼我想你將不得不執行2個取數操作,第一個是取所有頻道,然後我上面提到的第二個取數操作就是在哪裏您將提取限制設置爲3 – Zhang 2015-02-10 08:21:45

+0

謝謝。但是使用NSFetchedResultsController,我只能使用一個NSFetchRequest或不使用? – mike 2015-02-10 08:26:30

+0

對不起,邁克,我從來沒有使用NSFetchResultsController之前,我傾向於在我的ViewControllers或PersistentStack核心數據單例中寫所有我的讀取操作:P。我還想提到的一點是,有一種方法**有效地重用謂詞**:http://stackoverflow.com/questions/7708541/reuse-nspredicate-for-new-variable-substitute你應該使用這個用我的想法代替你的頻道名稱。 – Zhang 2015-02-10 08:28:41

回答

0

我發現了一個變通辦法爲我的問題(這是避免CoreData錯誤)。但是我沒有找到如何獲得3 PER PER通道的解決方案(仍然對此感興趣)。

如果你們其中一個人有同樣的問題 - 在這裏我的解決方法:
不用刪除一節的最後一個(第三)行並插入一個新的我剛剛更新了細胞像這樣的:

- (void)controller:(NSFetchedResultsController*)controller 
    didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath*)theIndexPath 
     forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath*)newIndexPath 
{ 

... 

    switch (type) { 
    case NSFetchedResultsChangeInsert: 
     if (newIndexPath.row < self.numberOfNewsItemsToFetch) { 
      id<NSFetchedResultsSectionInfo> sectionInfo = [controller sections][newIndexPath.section]; 
      NSInteger numberOfRowsInSection = [sectionInfo numberOfObjects]; 
      if (numberOfRowsInSection >= self.numberOfNewsItemsToFetch) { 
       NSIndexPath* indexPath = nil; 
       for (NSUInteger i = newIndexPath.row; i < self.numberOfNewsItemsToFetch; i++) { 
        indexPath = [NSIndexPath indexPathForRow:i inSection:newIndexPath.section]; 
        [self fetchedResultsController:controller configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
       } 
      } 
      else { 
       [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      } 
     } 
     break; 
... 
    } 
} 
相關問題