问题
I've been looking into this issue for the last day, so I think it's time to ask the question.
I created a one-to-many self referencing relation in CoreData to store contacts and group these contacts.
Contacts that haven't got a parent actually hold the "section name" of its children.
Section name (object without parent)
-------------------------------------
Contact 1
Contact 2
Code to save the objects (simplified):
//Create Section
section = [NSEntityDescription insertNewObjectForEntityForName:@"Contact" inManagedObjectContext:_managedObjectContext];
[section setValue:self.sectionField.text forKey:@"name"];
[section setValue:nil forKey:@"parent"];
[_managedObjectContext save:&error];
//Create contact
NSManagedObject *newContact = [NSEntityDescription
insertNewObjectForEntityForName:@"Contact"
inManagedObjectContext:_managedObjectContext];
[newContact setValue:self.nameField.text forKey:@"name"];
[newContact setValue:self.numberField.text forKey:@"data"];
[newContact setValue:[NSString stringWithFormat:@"%@",[LoginController getUser][@"id"]] forKey:@"user_id"];
[newContact setValue:section forKey:@"parent"];
Tableviewcontroller:
In viewWilAppear
I fetch all "parent"-objects (=sections) for the table view and assign them to the self.sections
property.
//In viewWillAppear I get all "parent" objects
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Contact" inManagedObjectContext:_managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
// Set predicate
[request setRelationshipKeyPathsForPrefetching: [NSArray arrayWithObject:@"children"]];
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(parent == nil) AND (children.@count > 0)"];
[request setPredicate:predicate];
self.sections = (NSMutableArray *)[_managedObjectContext executeFetchRequest:request error:nil];
Then in cellForRowAtIndexPath I try to retrieve the child with index at indexPath.row within the parent with index at indexPath.section.
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
Contact * section = [self.sections objectAtIndex:indexPath.section];
NSArray * contacts = [section.children allObjects];
Contact * contact = [contacts objectAtIndex:indexPath.row];
NSLog(@"contact %@", contact.name);
[cell.textLabel setText:contact.name];
[cell.detailTextLabel setText:contact.data];
UIImageView *call = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Call"]];
[cell setAccessoryView:call];
return cell;
The name of the contact won't show and I'm getting kind of desperate here. Any other insights?
回答1:
In addition to your own answer, you have another issue:
This line:
NSArray *contacts = [section.children allObjects];
is getting an array (allObjects) from a set. A set has no order so each time you request this array it will have a different order. This means that your cells don't have deterministic content, you will have duplicate rows and missing rows.
You could change the relationship to be ordered, or you could sort the array you get. You need to do one of these things before calling objectAtIndex:
will return sane results.
回答2:
The NSManagedObject class for the entity was not correct. I wasn't aware of the tool to automatically generate these objects for core data entities.
New file.. > Core Data > NSManagedObject subclass > Choose the correct Datamodel > Choose the correct entity.
来源:https://stackoverflow.com/questions/22555166/coredata-returning-set-with-empty-objects