无法正确获取对象 CoreData

Cannot fetch object CoreData correctly

我正在练习使用 CoreData 存储数据和获取数据。 但是我遇到了一些让我困惑了几个小时的问题。 我存储了一组从索引 0 到 107 的对象,一共是 108 个。它完美地工作。

存储的一些数据的NSLog:

2015-03-04 16:39:29.825 Colo[32365:1884749] <NSManagedObject: 0x7f83d06a7240> (entity: Color; id: 0xd000000000300000 <x-coredata://3DC5B29F-DA7C-4D7C-9D59-738A28A957C1/Color/p12> ; data: {
  colorArray = nil;
  fifthColor = "#5A3431";
  firstColor = "#F2EDDA";
  fourthColor = "#A65F4B";
  hexString = nil;
  index = 106;
  secondColor = "#BEAC94";
  star = 12;
  thirdColor = "#DA896E";
  title = "wm102\n        \n        ";
})
2015-03-04 16:39:29.826 Colo[32365:1884749] 107
2015-03-04 16:39:29.826 Colo[32365:1884749] <NSManagedObject: 0x7f83d06a7330> (entity: Color; id: 0xd000000000980000 <x-coredata://3DC5B29F-DA7C-4D7C-9D59-738A28A957C1/Color/p38> ; data: {
  colorArray = nil;
  fifthColor = "#242613";
  firstColor = "#100C17";
  fourthColor = "#FFE8B4";
  hexString = nil;
  index = 107;
  secondColor = "#604325";
  star = 12;
  thirdColor = "#D0A17D";
  title = "Create Now 2014 \U4f1a\U5834\n        \n        ";
})

但是当我尝试获取我存储到 CoreData 的这些对象时。

- (void)fetchDataFromCoreData
{
  AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
  NSManagedObjectContext *context = [delegate managedObjectContext];

  NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Color"
                                                     inManagedObjectContext:context];
  NSFetchRequest *request = [[NSFetchRequest alloc] init];
  [request setEntity:entityDescription];

  NSError *error;

  NSArray *objects = [context executeFetchRequest:request error:&error];

  if (!objects){
    NSLog(@"There was an error.");
  }

  for (NSManagedObject *oneObject in objects){
    NSString *title       = [oneObject valueForKey:@"title"];
    NSString *star        = [oneObject valueForKey:@"star"];
    NSString *index       = [oneObject valueForKey:@"index"];
    NSString *firstColor  = [oneObject valueForKey:@"firstColor"];
    NSString *secondColor = [oneObject valueForKey:@"secondColor"];
    NSString *thirdColor  = [oneObject valueForKey:@"thirdColor"];
    NSString *fourthColor = [oneObject valueForKey:@"fourthColor"];
    NSString *fifthColor  = [oneObject valueForKey:@"fifthColor"];
    int i = [index intValue];
    NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
    ColorCell *cell = (ColorCell *)[self.tableView cellForRowAtIndexPath:path];

    UIColor *first  = [Parser translateStringToColor:firstColor];
    UIColor *second = [Parser translateStringToColor:secondColor];
    UIColor *third  = [Parser translateStringToColor:thirdColor];
    UIColor *fourth = [Parser translateStringToColor:fourthColor];
    UIColor *fifth  = [Parser translateStringToColor:fifthColor];

    cell.firstColor.backgroundColor  = first;
    cell.secondColor.backgroundColor = second;
    cell.thirdColor.backgroundColor  = third;
    cell.fourthColor.backgroundColor = fourth;
    cell.fifthColor.backgroundColor  = fifth;
  }
}

不幸的是,cellForRowAtIndexPath中的cell以一种奇怪的方式重复使用,一些单元格是空白的,只出现一个单元格。我在

下了两个断点
     int i = [index intValue];
     NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];

而且我注意到索引是 break,82 应该是 81 的下一个。

任何想法都会受到欢迎。

这是我的第一次 CoreData 实践。请帮助我变得更好。

编辑:子类NSManagedObject: .h:

@interface ColorManagerObject : NSManagedObject

@property (nonatomic) UIColor *firstColor;
@property (nonatomic) UIColor *secondColor;
@property (nonatomic) UIColor *thirdColor;
@property (nonatomic) UIColor *fourthColor;
@property (nonatomic) UIColor *fifthColor;

@end

.m:

- (void)setFirstColor:(UIColor *)firstColor
{
  [self setValue:firstColor forKey:@"firstColor"];
}

- (UIColor *)firstColor
{
  NSString *string = [self valueForKey:@"firstColor"];
  return [Parser translateStringToColor:string];
}
  1. 您的 fetchRequest 没有 sortDescriptors,因此对象未按特定顺序返回。
  2. 这不是 tableView 的工作方式。

我们先解决第一个问题,简单的添加一个NSSortDescriptor。

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
NSSortDescriptor *indexSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES];
request.sortDescriptors = @[indexSortDescriptor];

第二个问题解释起来比较复杂。 TableView 使用数据源模式。它向您的数据源询问对象,您不将对象发送到 tableView。您应该将获取的结果存储在一个 NSArray 中,并将该数组用作您的数据源。然后实现三个基本的 UITableViewDataSource 方法。

例如:

@property (strong, nonatomic) NSArray *objects;

- (void)fetchDataFromCoreData {
    // ...
    self.objects = [context executeFetchRequest:request error:&error];
    [self.tableView reloadData]; // reload tableView so it contains all the new objects
    // ...
}

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.objects count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    }
    NSManagedObject *object = self.objects[indexPath.row];
    cell.textLabel.text = [object valueForKey:@"title"];
    return cell;
}

一旦成功,您可能想阅读有关 NSFetchedResultsController 的内容,它基本上是为由 Core Data 支持的 UITableViews 制作的。它提供了一个很好的委托,当从 CoreData 中插入或删除对象时,它将插入和删除单元格。

您可能还想查看 NSManagedObject 的子类,这样您就不必使用 [object valueForKey:@"title"],而是可以使用 object.title