CoreData - 如何使用validateForDelete:确定是否应删除托管对象

时间:2013-12-21 19:38:00

标签: ios core-data

目标:我想检查一个托管对象,以确保可以删除

期望: -[NSManagedObject validateForDelete:]应根据托管对象模型中的删除规则设置返回BOOL

<小时/>

NSManagedObject类参考

  

validateForDelete:

     

确定是否可以在当前状态下删除接收器。

     

- (BOOL)validateForDelete:(NSError **)error

     

参数

     

错误

     

如果无法在当前状态下删除接收器,则返回时包含描述问题的NSError实例。

     

返回值

     

YES如果可以在当前状态下删除接收者,否则NO

     

讨论

     

如果对象具有“拒绝”删除规则并且该关系具有目标对象,则无法删除该对象。

     

NSManagedObject的实现向接收者的实体描述发送一条消息,该消息根据值的存在与否进行基本检查。

阅读本文我假设我应该能够做到这样的事情:

BOOL canDelete = [myManagedObject validateForDelete:&error];

if (canDelete) {
    [managedObjectContext deleteObject:myManagedObject];
}
else {
    [self requestUserFeedback];
}

但是,此方法几乎总是返回NO

<小时/>

示例代码

托管对象模型

Department
 - Attribute: name  
     - Value: String
 - Relationship: employees
     - To Many
     - Destination: Employee
     - Delete Rule: Nullify
     - Inverse: department

Employee
 - Attribute: name
     - Value: String
 - Relationship: department
     - To One
     - Destination: Department
     - Delete Rule: Nullify
     - Inverse: employees

示例代码:

NSManagedObject *department = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:self.managedObjectContext];

for (int i = 0; i < 10; i++) {
    NSManagedObject *employee = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.managedObjectContext];
    [employee setValue:department forKey:@"department"];
    if ([employee validateForDelete:NULL]) {
        NSLog(@"Can delete employee");
    }
    else {
        NSLog(@"WARNING: Cannot delete employee");
    }
}

NSError *error;
BOOL canDelete = [department validateForDelete:&error];
if (canDelete) {
    NSLog(@"Can delete department");
}
else {
    NSLog(@"WARNING: Cannot delete department");
}

输出:

  

可以删除员工
  可以删除员工
  可以删除员工
  可以删除员工
  可以删除员工
  可以删除员工
  可以删除员工
  可以删除员工
  可以删除员工
  可以删除员工
  警告:无法删除部门

令我惊讶的是,canDeleteNO。当员工对象无效时,为什么删除部门对象无效?返回的错误包含以下(缩写)

Error Domain=NSCocoaErrorDomain
Code=1600
UserInfo= <>{
    NSValidationErrorObject=< department object >
    NSValidationErrorKey=employees
    NSValidationErrorValue=Relationship 'employees' on managed object
}

因此,validateForDelete:没有返回我对多个关系的期望,但确实返回了一对一关系的预期值。但是,请回到文档中一秒钟:

  

如果对象具有 [sic] “拒绝”删除规则并且该关系具有目标对象,则无法删除该对象。

     

NSManagedObject的实现向接收者的实体描述发送一条消息,该消息根据值的存在与否进行基本检查。

这将调出validateForDelete:的默认实现如何工作并协同努力以引起对“拒绝”删除规则的注意。没有提及无效或级联删除规则或者一对一或多对多关系之间的差异。

<小时/>

进一步研究

谷歌搜索出现this hit on the Apple Mailing List archives from 2009,基本上说:-[NSManagedObject validateForDelete:]是子类的钩子,你需要在一个单独的方法中实现自己的逻辑,以确定一个对象是否有效删除。

什么?这是真的?这不是这种方法的文档会让人相信:

  

确定是否可以在当前状态下删除接收器。


我们如何检查托管对象是否处于可以删除的状态?

我在GitHub上设置了一个小样本项目,用于说明我在生产代码和单元测试中的发现。

1 个答案:

答案 0 :(得分:0)

我阅读文档的方式是你应该对它进行子类化,但你的子类也应该首先调用super,这样如果框架本身有验证,你也会捕获它。

根据我的经验,-validateForDelete:只会在拒绝规则上返回NO

我的建议是将关系规则设置为&#34; No Action&#34;然后在子类中实现逻辑。

在您的子类中,您可以检查与部门/教室的关系,如果计数为零,则返回YES。非常简单的删除验证规则,无法在模型中实现。