一对多关系:CoreData

我对coredata相当陌生,一直困在一个问题上。 任何援助将不胜感激。

信息:我有一个核心数据应用程序与实体; 列表和任务。 列表和任务有一个一对多的关系。

Task.h

@class List; @interface Task : NSManagedObject @property (nonatomic, retain) NSString * task; @property (nonatomic, retain) NSString * note; @property (nonatomic, retain) List *list; @end 

List.h

 @class Task; @interface List : NSManagedObject @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSDate * dateCreated; @property (nonatomic, retain) NSNumber * sortOrder; @property (nonatomic, retain) NSSet *task; @end @interface List (CoreDataGeneratedAccessors) - (void)addTaskObject:(Task *)value; - (void)removeTaskObject:(Task *)value; - (void)addTask:(NSSet *)values; - (void)removeTask:(NSSet *)values; @end 

我使用;

  NSManagedObjectContext *context = [self managedObjectContext]; if ([self.listTextField.text length] == 0) { // Quit here if no text is entered [self dismissViewControllerAnimated:YES completion:nil]; return; } // Create a new list. // Create an NSManagedObject for our database entity. list = [NSEntityDescription insertNewObjectForEntityForName:@"List" inManagedObjectContext:context]; // Add the new task to the object (which in turns adds to our database). [list setValue:self.listTextField.text forKey:@"name"]; // Get current date and time. NSDate *todayDate = [NSDate date]; // Add the date to the object (which in turns adds to our database). [list setValue:todayDate forKey:@"dateCreated"]; NSError *error = nil; // Save the object to persistent store if (![context save:&error]) { NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); } [self dismissViewControllerAnimated:YES completion:nil]; 

我可以使用cellaccessorybuttontaped下面的代码更新已经创build的列表;

 NSManagedObjectContext *context = [self managedObjectContext]; if ([self.listTextField.text length] == 0) { // Delete object from database. [context deleteObject:self.list]; NSError *error = nil; // Save the action to persistent store if (![context save:&error]) { NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); } [self dismissViewControllerAnimated:YES completion:nil]; } else { // Update existing task. [self.list setValue:self.listTextField.text forKey:@"name"]; // Get current date and time. NSDate *todayDate = [NSDate date]; // Add the date to the object (which in turns adds to our database). [list setValue:todayDate forKey:@"dateCreated"]; NSError *error = nil; // Save the action to persistent store if (![context save:&error]) { NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); } } [self dismissViewControllerAnimated:YES completion:nil]; 

然后我可以导航到一个列表。

我的问题是,我怎么才能创build一个我已经导航到列表的任务? 已经有2天了,我在Google上找不到任何东西。


据我所build议,

 @property (strong, nonatomic) List *selectedList; 

我现在有这个作为我的保存方法

NSManagedObjectContext * context = [self managedObjectContext];

 // Saving a new task. Task *task = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:context]; task.task = self.taskText.text; task.note = self.noteText.text; task.list = self.selectedList; NSLog(@"The selected list is: %@", [self.selectedList description]); NSError *error = nil; // Save the object to persistent store if (![context save:&error]) { NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); } [self.selectedList addTaskObject:task]; [self dismissViewControllerAnimated:YES completion:nil]; 

新任务已创build,但会在所有列表中创build。 有没有可能这是工作,我不是基于他们的列表获取任务?

当我导航到列表中时,这是我的提取请求:

 if (fetchedResultsController != nil) { return fetchedResultsController; } // Create a fetch request. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; // Create an entity so fetch the data from. NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:self.managedObjectContext]; // Set the entity of the fetch request. [fetchRequest setEntity:entity]; // Set the amount to be fetched at a time [fetchRequest setFetchBatchSize:20]; // Create a sort descriptor. NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"task" ascending:NO]; // Attach the sort descriptor to the fetch request. NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; // Create a fetch result controller using the fetch request NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; self.fetchedResultsController = theFetchedResultsController; theFetchedResultsController.delegate = self; // Perform fetch. NSError *error = nil; if (![self.fetchedResultsController performFetch:&error]) { // Handle error. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); exit(-1); // Fail } return fetchedResultsController; 

你需要跟踪你已经导航到的列表。 一种做法是创build一个名为parentList的属性

 @property(nonatomic,strong) List *parentList 

在视图控制器中创build一个任务。在导航到视图控制器之前设置此属性。

在任务视图控制器中,您使用Task *reqdTask = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:context];执行类似于List对象的插入操作Task *reqdTask = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:context]; 然后设置所有的值一旦Savebutton被按下。

 [parentList addTaskObject: reqdTask]; 

你完成了 这将在任务实体中创build一个Task并将其映射到List实体。 希望这可以帮助。

**编辑***

你需要这样做[parentList addTaskObject: reqdTask]; 保存你的上下文之前。

将其添加到NSFectResultsController
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"list = %@",self.parentList]];

所以它会是这样的

 // Create a fetch request. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; // Create an entity so fetch the data from. NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:self.managedObjectContext]; // Set the entity of the fetch request. [fetchRequest setEntity:entity]; // Set the amount to be fetched at a time [fetchRequest setFetchBatchSize:20]; // Create a Predicate. [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"list = %@",self.parentList]]; //continue 

这将带来与选定列表关联的任务。

这就是你的实体头中的这些方法:

 - (void)addTaskObject:(Task *)value; - (void)removeTaskObject:(Task *)value; - (void)addTask:(NSSet *)values; - (void)removeTask:(NSSet *)values; 

您将创build一个新的任务实体:

 Task *t = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:context]; 

然后像在列表对象中一样完成其中的字段:

 t.task = @"Whatever"; t.note = @"Whatever Note"; t.list = currentlySelectedListItem; // whatever that happens to be -- it will be a (List *)something 

然后,您要将任务对象添加到列表中:

 [currentlySelectedListItem addTask:t]; 

然后保存上下文,你就完成了。

这里关键的是通过向NSSet中包含的一组任务值添加一个任务来有效地更新List对象。 而t.list将包含一个指向父List对象的指针。

在我看来,你把它摆好了(我假设:

 @property (nonatomic, retain) List *list; 

是与父列表的关系,而不仅仅是你定义的另一个值; 看起来是这样的)。