2015-03-04 3 views
0

Я использую CoreData для хранения данных и получения данных. Но я встретил некоторые проблемы, которые смутили меня в течение нескольких часов. Я сохранил группу объектов из индекса 0 - 107, всего 108. Он отлично работает.Не удается правильно получить объект CoreData

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; 
    } 
} 

К сожалению, cell в cellForRowAtIndexPath повторно странным образом, некоторые клетки являются пустыми, и появляются только одна клетка. Я сделал две контрольные точки на

 int i = [index intValue]; 
    NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0]; 

И я заметил, что индекс перерыв, который 82 должен быть следующий один из 81.

Любая идея будет очень приветствоваться.

enter image description here enter image description here

Это моя первая практика CoreData. Пожалуйста, помогите мне стать лучше.

EDIT: Подкласс 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
  1. Ваш fetchRequest не имеет sortDescriptors, поэтому объекты не возвращаются в определенном порядке ,
  2. Это не то, как tableViews работает.

Сначала исправим первую проблему, просто добавим NSSortDescriptor.

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

Вторая проблема сложнее объяснить. TableView использует шаблон dataSource. Он запрашивает ваш источник данных для объектов, вы не отправляете объекты в 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, который в основном сделан для UITableViews, которые при поддержке Core Data. Он предлагает приятный делегат, который будет вставлять и удалять ячейки, когда объекты вставлены или удалены из CoreData.

Возможно, вы также захотите ознакомиться с подклассами NSManagedObject, поэтому вам не нужно использовать [object valueForKey:@"title"] и вместо этого можете использовать object.title.

+0

СПАСИБО! Вы совершенно правы!И так я использовал для установки tableView. Удивительный класс «NSFetchedResultsController», о котором вы говорили. Кстати, я подклассифицировал 'NSManagedObject', но, похоже, я встретил некоторую проблему. Я редактирую свой пост, включив его. –

Смежные вопросы