0

我正在对Core Data 进行一些测试,假设我有一个带有navigationBar 和addButton 的mainViewController。单击 addButton 将打开一个 detailViewController。当我按保存插入新对象时,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 来处理设置其数据?

例如

这样,我将 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];   
}

这些代码只是用于教育目的的伪代码。所有方法都有效,我只想知道您认为哪种方法最正确以及为什么。谢谢

4

3 回答 3

1

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

于 2013-09-05T21:51:11.430 回答
0

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

[self.managedObjectContext rollback]

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

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

  1. 第一种方法允许我在 saveObject 方法中编写额外的代码。假设您想在保存对象之前验证一些属性。这些属性只存在于 detailViewController 中。因此,如果不将每个属性显式传递回委托函数(这可能会变得混乱),您就不能在这种情况下使用委托。
  2. 现在,假设您正在 mainViewController 中创建一个对象,而 detailViewController 仅用于填充在 mainViewController 中创建的对象的字段。在这种情况下,我会使用委托方法并将字段传递回 mainViewController,这样当用户将对象保存在 mainViewController 中时,字段值也会随之保存。如果用户取消 mainViewController,则字段值也不会保存。
于 2013-09-06T02:31:37.443 回答
0

这听起来像是一个完美的NSFetchedResultsController. ANSFetchedResultsController是一个对象,使显示核心数据中的数据UITableView变得更加容易。它甚至会告诉您核心数据中与谓词匹配的对象何时发生变化(插入、删除、更新、移动)。

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

由于MainViewControllerNSFetchedResultsController,它会自动知道一个新对象已经创建并且可以更新UITableView来显示它。

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

于 2013-09-05T22:02:03.173 回答