核心数据:在表格视图中滚动时,存储在数组中的 NSManagedObjects 变为 nil

Posted

技术标签:

【中文标题】核心数据:在表格视图中滚动时,存储在数组中的 NSManagedObjects 变为 nil【英文标题】:Core Data: NSManagedObjects stored in array turn into nil when scrolling in table view 【发布时间】:2016-02-25 15:29:37 【问题描述】:

我有一些 NSManagedObjects 我正在检索并存储在一个数组中以填充表视图。当视图第一次加载时,所有数据都在那里,但是当我滚动数组中的 NSManagedObjects 时变为 nil。

我在viewDidLoad中获取这样的:

AppDelegate *appDelegate = [[AppDelegate alloc] init];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tracks" inManagedObjectContext:appDelegate.managedObjectContext];
[fetchRequest setEntity:entity];

NSError *error = nil;
NSArray *fetchedObjects = [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) 
    NSLog(@"An Error! %@",error);


mutArray = [[NSMutableArray alloc] initWithArray:fetchedObjects]; 

我的 NSManagedObject 子类被命名为“Tracks”。当视图加载时,我可以从 mutArray 分配一个 Tracks 对象,但是当我滚动时,Tracks 对象总是为零。这是我的cellForRowAtIndexPath 方法:

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

    static NSString *simpleTableIdentifier = @"TracksCell";

    TracksCell *cell = (TracksCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    if (cell == nil)
    
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TracksCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    

    Tracks *track = [mutArray objectAtIndex:indexPath.row];

    cell.titleLabel.text = track.name;
    cell.addressLabel.text = [NSString stringWithFormat:@"%@, %@",track.city,track.state];

    return cell;


所以为了清楚起见,这在表格第一次加载时有效。但是如果我向下滚动,那么第一行上的 Tracks 对象是 nil。当我向下滚动时,任何尚未加载的行(在视图下方)都为零。

我在这里错过了什么?

【问题讨论】:

如果您在初始加载后在cellForRowAtIndexPath 中设置断点 - 您在mutArray 中还有数据吗? 您缺少NSFetchedResultsController 的完美用例。 为什么数组是可变的?您是否故意从其他地方移除项目? @JanGreve 你能解释一下在这种情况下我应该如何使用 NSFetchedResultsController 吗?但是是的,数组是可变的是有原因的,我有一个搜索栏和一些逻辑,用于单击每个单元格上的收藏按钮。所有这些代码现在都被注释掉了,直到我可以让单元格实际填充来自 Core Data 的信息 developer.apple.com/library/ios/documentation/Cocoa/Conceptual/… 【参考方案1】:

感谢@JanGreve 在 cmets 中发布文档,这就是任何需要帮助设置 NSFetchedResultsController 的人的答案。

在您的 .h 文件中:

添加<NSFetchedResultsControllerDelegate>

并添加属性:

@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;

在您的 .m 文件中:

@synthesize fetchedResultsController = _fetchedResultsController;

viewDidLoad:

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) 
    NSLog(@"Error! %@",error);
    abort();

添加此方法以填充您的 fetchedResultsController:

#pragma mark -
#pragma mark Fetched Results Controller section
-(NSFetchedResultsController *) fetchedResultsController 
    if (_fetchedResultsController != nil) 
        return _fetchedResultsController;
    

    AppDelegate *appDelegate = [[AppDelegate alloc] init];

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

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    _fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

然后在我的cellForRowAtIndexPath: 中,像这样填充你的 NSManagedObject 子类:

Tracks *track = [self.fetchedResultsController objectAtIndexPath:indexPath];

【讨论】:

以上是关于核心数据:在表格视图中滚动时,存储在数组中的 NSManagedObjects 变为 nil的主要内容,如果未能解决你的问题,请参考以下文章

滚动到顶部时在表格视图的开头动态添加行

表格视图中的慢速/口吃滚动

如何将CGPoint存储在核心数据中?

如何更改表格视图中的标签文本颜色(存储在数组中的数据)

当我滚动表格视图时,文本字段中的数据设置为 null

TabBar 项目 - 表格视图中的核心数据