核心数据 - 添加对象的许多方法

时间:2013-09-05 21:37:36

标签: ios objective-c uitableview core-data

我正在对Core Data进行一些测试,假设我有一个带有navigationBar和addButton的mainViewController。 单击addButton将打开detailViewController。当我按下save来插入一个新的Object时,detailVieController将关闭并显示插入了新数据的表。 我可以想到两种不同的方式。

第一种方法 - 传递ManagedObjectContext 在添加按钮的操作中,我创建了一个新的detailViewController的实例,并将managedObjectContext传递给它。因此将是detailViewController的保存按钮,它将负责保存上下文然后弹出控制器。

这是MainViewController中addButton调用的方法

     -(void)addNewObject{
       DetailViewController *detVC = [DetailViewController alloc]initWhit:self.managedObjectCOntext];
       [self.navigationcontroller pushViewController:detVC animated:YES];
       }

此方法由IngredientViewController

中的保存按钮调用
      -(void)saveObject{
       NSError *error;
        if (![self.managedObjectContext save:&error]){
         NSLog(@"Error");
         }
       }

第二种方法 - 使用代理人 在addButton的动作中我创建了一个DetailViewController的实例,我将其设置为委托,所以当我按下DetailViewCOntroller中的保存按钮时,将调用将数据传递给主控制器的委托。

这是MainViewController中addButton调用的方法

 (void)addNewObject{
       DetailViewController *detVC = [DetailViewController alloc]init];
       detVC.delegate = self;
       [self.navigationcontroller pushViewController:detVC animated:YES];
       }

此方法由IngredientViewController

中的保存按钮调用
      -(void)saveObject{
       [self.delegate detailVCdidSaveObject];
       }

这是在mainViewController中实现的委托

detailVCdidSaveObject{
           NSError *error;
            if (![self.managedObjectContext save:&error]){
             NSLog(@"Error");
             }
           }

------------------------------ 传递对象

最好将原始数据传递给DetailViewController并在那里创建对象,或者最好将对象的实例传递给DetailViewController,它将处理settin的数据?

例如

这样我将mainVC的对象实例链接到一个DetailVC,这样我就可以轻松设置其值

-(void)addObject{

    DetailViewController *detailVC =[[DetailViewController alloc]init];
    detailVC.delegate = self;

    self.object = [NSEntityDescription insertNewObjectForEntityForName:@"Object" inManagedObjectContext:self.managedObjectContext];
    detailVC.object = self.object;
    [self.navigationController pushViewController:detailVC animated:YES];   
}

这样我传递原始数据并让detailVC创建实例

-(void)addObject{
DetailViewController *detailVC =[[DetailViewController alloc]initWithName:@"objname"];
[self.navigationController pushViewController:detailVC animated:YES];   
}

这些代码只是用于教育目的的伪代码。各种方式都有效,我只想知道你认为哪种方式最正确,为什么。感谢

3 个答案:

答案 0 :(得分:1)

我使用了前两种方法,在我看来它们同样有效(尽管我个人更喜欢委托)。但是,如果您为用户提供取消或返回导航控制器的选项,则第三种方法会导致问题。如果发生这种情况,您将拥有一个您永远不需要创建的对象。

答案 1 :(得分:0)

这听起来像NSFetchedResultsController的完美用例。 NSFetchedResultsController是一个对象,可以更轻松地显示UITableView中核心数据的数据。它甚至会告诉您核心数据中与谓词匹配的对象何时发生更改(插入,删除,更新,移动)。

所以我这样做的方式是MainViewController会有NSFetchedResultsControllerUITableView提供数据。当您按下添加按钮时,它将执行您在第一种方法中所拥有的操作。 DetailViewController将创建新实例,在其上设置值,然后保存managedObjectContext

由于MainViewController包含NSFetchedResultsController,因此会自动知道已创建新对象,并且可以更新UITableView以显示该对象。

NSFetchedResutsController documentationNSFetchedResutsControllerDelegate documentation向您展示如何将其与UITableView一起使用,包括您可以复制到视图控制器中的代码,以完成大部分工作。

答案 2 :(得分:0)

实际答案取决于您的偏好。在我的项目中,我实现了前两种方法。由于凯文提到的相同原因,我的第三种方法肯定是否定的。如果用户取消操作或发生了某些错误,那么您必须注意删除更改(也许在您的didMoveToParentViewController方法中写下以下代码并取消方法): -

[self.managedObjectContext rollback]

当然假设您没有任何其他进程同时修改该managedObjectContext。

现在,我更喜欢前两种方法,因为: -

  1. 第一种方法允许我在saveObject方法中编写其他代码。假设您要在保存对象之前验证某些属性。这些属性仅存在于detailViewController中。因此,在没有明确地将每个属性传递回委托函数(这可能会变得混乱)的情况下,您无法在该情况下使用委托。
  2. 现在,假设您正在mainViewController中创建一个对象,而detailViewController仅用于填充在mainViewController中创建的对象的字段。在这种情况下,我会使用委托方法并将字段传递回mainViewController,以便当用户将对象保存在mainViewController中时,字段值随之保存。如果用户取消mainViewController,则也不会保存字段值。