【问题标题】:Data from Core Data won't show up in the Table Cell (using FetchResultsController)Core Data 中的数据不会显示在表格单元格中(使用 FetchResultsController)
【发布时间】:2014-07-23 17:53:24
【问题描述】:

我有一个 TableViewController (favTable) 的子类,一个原型自定义单元格 (favCell),其中包含在情节提要中设计的两个文本标签,以及一个核心数据模型 (DataModel),其中包含一个实体 (FavoritesInfo) 和两个属性 (name、score) .我还创建了 NSManagedObject (FavoritesInfo) 的子类。当我运行该应用程序时,单元格根本没有内容。 我一直在阅读几个不同的教程并结合不同的方法。一定有什么乱七八糟的。我不知道如何显示单元格内容。任何帮助表示赞赏。

favTable.h

#import <UIKit/UIKit.h>
#import "favCell.h"


@interface favTable : UITableViewController  <NSFetchedResultsControllerDelegate> 
{
    NSFetchedResultsController *fetchedResultsController;
   NSManagedObjectContext *managedObjectContext;

}


@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;



@end

favTable.m

#import "favTable.h"
#import "ecoAppDelegate.h"
#import "favCell.h"
#import "FavoritesInfo.h"




@interface favTable ()


@end

@implementation favTable


@synthesize managedObjectContext;
@synthesize fetchedResultsController = _fetchedResultsController;


- (NSFetchedResultsController *)fetchedResultsController {
    if (!_fetchedResultsController) {

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

        NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];



        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

        [fetchRequest setFetchBatchSize:20];


        NSFetchedResultsController *theFetchedResultsController =
        [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                            managedObjectContext:managedObjectContext sectionNameKeyPath:nil
                                                       cacheName:@"Root"];
        _fetchedResultsController = theFetchedResultsController;
        _fetchedResultsController.delegate = self;
    }


    return _fetchedResultsController;

}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.title = @"Favorites";


    self.navigationController.navigationBar.translucent = NO;



    self.managedObjectContext = ((ecoAppDelegate *) [UIApplication sharedApplication].delegate).managedObjectContext;



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

    fetchRequest.resultType = NSDictionaryResultType;

    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"name", nil]];


    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }



}

- (void)viewDidUnload
{


    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

    self.fetchedResultsController = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
//    return [favName count];

    id  sectionInfo =
    [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];

}





- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{


    static NSString *CellIdentifier = @"favCell";


    favCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[favCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...

   [self configureCell:cell atIndexPath:indexPath];


    return cell;
}


- (void)configureCell:(favCell *)cell
          atIndexPath:(NSIndexPath *)indexPath
{

    FavoritesInfo*favoritesInfo = [self.fetchedResultsController objectAtIndexPath:indexPath];


    cell.cellname.text = favoritesInfo.name;
    cell.cellscore.text = favoritesInfo.score;

    }







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

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

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

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

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

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

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

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath]
                    atIndexPath:indexPath];
            break;

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

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

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */
}

@end

【问题讨论】:

  • 第一条评论。您在这里使用了一些非常古老的编码技术。您应该删除 iVar 和 @synthesize 行以开始。您现在可以对数组使用文字 @[object] 而不是 ...initWithObjects:object, nil] 等...
  • 另外,您是否尝试过调试它。您是否设置了断点以检查数据是否正在保存或您的 FRC 认为它有多少行等...如果您进行提取(没有 FRC),您是否看到任何提取结果等...
  • @Fogmeister 抱歉回复晚了,但我正在测试您的建议。我的数据正在保存,如果我在没有 FRC 的情况下进行提取,则会显示内容。代码不会进入 (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 的断点
  • 如果只有一个section,可以去掉numberOfSections方法。
  • @Fogmeister 我改了,还是不显示单元格内容

标签: ios objective-c uitableview core-data nsfetchedresultscontroller


【解决方案1】:

问题是您使用的是非常旧的代码样式,它让您感到困惑并导致此问题。

首先,删除 iVar。

您的 .h 文件应该是...

@interface favTable : UITableViewController

@end

是的,它真的应该没有任何东西。没有其他文件需要访问这些属性,所以不要把它们放在这里。

.m文件应该是这样的……

//the imports here...

@interface favTable () // the delegate and datasource come for free as a subclass of UITableViewController. Don't add them again.

// no ivars

@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

@end

@implementation favTable

// don't use @synthesize it is done automatically.

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.title = @"Favorites";

    self.navigationController.navigationBar.translucent = NO;

    self.managedObjectContext = ((ecoAppDelegate *) [UIApplication sharedApplication].delegate).managedObjectContext;

    NSError *error;

    // use dot syntax for accessing properties.
    // self.fetchedResultsController
    // not
    // [self fetchedResultsController]

    if (![self.fetchedResultsController performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }
}

- (NSFetchedResultsController *)fetchedResultsController
{
    // user the _propertyName in the getter and setter only **ish**.

    if (_fetchedResultsController) {
        return _fetchedResultsController
    }

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"FavoritesInfo"];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];

    [fetchRequest setSortDescriptors:@[sort]]; // new syntax, use it!

    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                        managedObjectContext:managedObjectContext sectionNameKeyPath:nil
                                                   cacheName:nil];

    _fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // now there's your problem
    // in here you were using `fetchedResultsController`. This is why you need to
    // drop the old style.
    // Because of your ivars fetchedResultsController != self.fetchedResultsController
    // or _fetchedResultsController

    id  sectionInfo =
    [self.fetchedResultsController sections][section]; // new syntax, use it!
    return [sectionInfo numberOfObjects];

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"favCell";

    favCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[favCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
   [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

- (void)configureCell:(favCell *)cell
          atIndexPath:(NSIndexPath *)indexPath
{
    FavoritesInfo*favoritesInfo = [self.fetchedResultsController objectAtIndexPath:indexPath];

    cell.cellname.text = favoritesInfo.name;
    cell.cellscore.text = favoritesInfo.score;
}

// all the FRC stuff here...

@end

这里有很多更新。他们中的大多数只是将语法更新为现代 Objective-C(现在已经超过 2 年了)。

你真的需要更新你的语法用法。正是新旧语法的结合导致了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多