NSFetchedResultsController - 如何在cellForRowAtIndexPath中显示正确的节行

时间:2013-09-05 10:29:22

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

我有一份JSON读入的国家/地区列表。它现在正确读入,似乎存储关系。

// Read JSON

NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"venues" ofType:@"json"];

    NSData *data = [NSData dataWithContentsOfFile:jsonPath];

    id json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

    if (error) {
        NSLog(@"Error - %@", error);
    } else {
        //NSLog(@"JSON = %@", json);


        dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
            /*
             "USA": [
             {
             "venue": "Von Braun Center",
             "city" : "Huntsville",
             "state": "Alabama",
             "capacity": 13760
             },
             */

            for (NSDictionary *dict in json) {
                NSString *name = (NSString *) [dict objectForKey:@"name"];
                NSArray *venueList = (NSArray *) [dict valueForKey:@"venues"];



                [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *c) {
                    Country *country = [Country createInContext:c];
                    [country setName:name];

                    NSMutableArray *listOfVenues = [NSMutableArray array];

                    NSLog(@"Country - %@", country.name);

                    for (NSDictionary *venueData in venueList) {

                        NSString *name = (NSString *) [venueData objectForKey:@"venue"];
                        NSString *city = (NSString *) [venueData objectForKey:@"city"];
                        NSString *state = (NSString *) [venueData objectForKey:@"state"];
                        //NSNumber *capacity = (NSNumber *) [NSNumber numberWithInt:[[venueData valueForKey:@"capacity"] intValue]];

                        Venue *v = [Venue createInContext:c];
                        [v setName:name];
                        [v setCity:city];
                        [v setState:state];
                        [v setCountry:country];
                        [listOfVenues addObject:v];
                        NSLog(@"Venue - %@, %@", v.name, v.country.name);
                    } // next

                    [country setVenues:[NSSet setWithArray:listOfVenues]];

                } completion:^{
                }];
            } // next

            dispatch_async(dispatch_get_main_queue(), ^{
                [[NSManagedObjectContext defaultContext] saveNestedContexts];                
                NSUInteger entities = [Venue countOfEntities];
                NSLog(@"Venues saved = %d", entities);
            });
        });

    } // end if

这会生成一个场地记录,就像这样;

加载场地数据......

Country - USA
Venue - Von Braun Center, USA
Venue - Birmingham Convention Center, USA

Country - UK
Venue - O2 Arena, UK
Venue - MEN Arena, UK

到目前为止一切顺利。

但是当我到达实际的Venue视图时,它只是按字母顺序显示场地,但它确实显示了正确的部分

我的代码是;

// viewDidLoad
    self.fetchedResultsController = [Venue fetchAllGroupedBy:@"country.name" withPredicate:nil sortedBy:@"name" ascending:YES];

#pragma mark - Table View

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];

}

-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo name];
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

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

    Venue *v = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = v.name;
}

屏幕上显示的内容如下:

我尝试重置应用及其数据无效。

屏幕截图(via Imageshack

正如您所看到的,该列表只是按字母顺序排列,并且不正确,并且不会在相关部分中拆分。

似乎源于

Venue *v = [self.fetchedResultsController objectAtIndexPath:indexPath];

但是我不确定如何解决它。

我想知道我做错了什么以及如何修复它以便它在正确的部分显示正确的数据。

2 个答案:

答案 0 :(得分:0)

为场地设置国家后

[v setCountry:country];

此行是多余的,可能会破坏您的关系

[country setVenues:[NSSet setWithArray:listOfVenues]];

您只需设置一次关系。反向关系自动生成。

答案 1 :(得分:0)

我能够将这些部分放在正确的组中(即:美国场地现在属于美国国家)

self.fetchedResultsController = [Venue fetchAllGroupedBy:@"country.name" withPredicate:nil sortedBy:@"country.name" ascending:YES delegate:self inContext:managedObjectContext];

但现在发生的事情是场地没有按名称升序排序。

我得到这样的清单;

截图: http://img443.imageshack.us/img443/340/6f3o.png

场地现已分组到各个国家/地区,但场地本身并未在A-Z中订购。

我希望我的场地安排在A-Z,不会订购国家。

但我不知道该怎么做。