NSComparisonPredicate 用于空对多关系

Posted

技术标签:

【中文标题】NSComparisonPredicate 用于空对多关系【英文标题】:NSComparisonPredicate for empty to-many relationship 【发布时间】:2013-09-15 02:33:03 【问题描述】:

我在 Core Data 中的两个实体(EntityA 和 EntityB)之间存在多对多关系,我正在尝试通过删除不再与任何实例有任何关系的 EntityB 实例来定期清理数据库实体A。我正在使用 Mogenerator 创建 .m 和 .h 文件,这允许我以我的方式引用属性/关系名称。

NSPredicate *noRelationPredicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionWithFormat:@"%K", EntityBRelationships.relationshipNameForEntityA] rightExpression:[NSExpression expressionWithFormat:@"nil"] modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0];

但是,我在执行 fetch 时遇到以下错误:'NSInvalidArgumentException',原因:'to-many key not allowed here'

我更喜欢使用类方法 NSComparisonPredicate predicateWithLeftExpression:rightExpression:modifier:type:options: 创建谓词,因为我试图在创建谓词时避免使用字符串文字。

【问题讨论】:

【参考方案1】:

您可以向实体 B 添加一个类别,以检查它是否可以被删除。

-(void)willSave 
    if (!self.aRelations.count && !self.isDeleted) 
        [self.managedObjectContext deleteObject:self];
    

(通过在单独的文件中使用类别,如果您想重新生成托管对象子类,则不会覆盖此代码。)

【讨论】:

谢谢 Mundi,我会试试这个 似乎 willSave 导致某种递归行为发生...我收到“无法在保存前处理挂起的更改。 100 次尝试后上下文仍然很脏。通常,这种递归污染是由错误的验证方法、-willSave 或通知处理程序引起的。' 实际上我通过检查是否 !self.deleted 来避免这个错误。但有时,我似乎过早地删除了 self,因为我的增量存储稍后会抛出此错误:'NSInvalidArgumentException',原因:'*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil' 你也可以试试-didSave。是的,我忘了包含 isDeleted 检查。【参考方案2】:

在定义关系时,可以指定 CoreData 对“孤立”实例的处理方式。请参阅此处的“关系删除规则”:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW1

特别是,您可以使用“级联”来为您处理删除。来自文档:

级联

删除关系目的地的对象。为了 例如,如果您删除一个部门,则解雇该部门的所有员工 同一部门。

【讨论】:

我之前尝试过使用级联,但是由于它是多对多的关系,所以它似乎没有像我预期的那样工作。也许我误解了它是如何工作的,但是我无法根据其他因素阻止删除......最终删除了我不想被删除的项目。

以上是关于NSComparisonPredicate 用于空对多关系的主要内容,如果未能解决你的问题,请参考以下文章

用于空值颤振的颤振空检查运算符

Flutter Bloc Test:空值检查运算符用于空值(空安全)

在运行时出现此错误“用于空值的空检查运算符”

Navigator.pushReplacement 提供用于空值的空检查运算符。这次是 - 状态

如何修复颤振中的“未处理的异常:用于空值的空检查运算符”错误?

如何在颤振发布方法中修复“未处理的异常:用于空值的空检查运算符”