【问题标题】:Custom initializer for an NSManagedObjectNSManagedObject 的自定义初始化程序
【发布时间】:2025-12-29 07:20:16
【问题描述】:

根据文档:

你不应该重写 init。不鼓励您覆盖 initWithEntity:insertIntoManagedObjectContext:

您应该改用 awakeFromInsert 或 awakeFromFetch。

如果我只想将某个属性设置为当前日期或类似日期,这很好,但如果我想发送另一个对象并根据其信息设置属性怎么办?

例如,在一个名为“Item”的 NSManagedObject 子类中,我想要一个 initFromOtherThing:(Thing *)thing,其中项目的名称设置为该事物的名称。我想避免“只需记住”每次在创建项目后立即设置名称,并且当我决定我希望 Item 还基于 Thing 设置另一个默认属性时必须更新十五个不同的控制器类。这些是与模型相关的操作。

我该如何处理?

【问题讨论】:

    标签: objective-c ios cocoa core-data nsmanagedobject


    【解决方案1】:

    我认为处理此问题的最佳方法是继承 NSManagedObject,然后创建一个类别来保存您要添加到对象的内容。例如几个用于唯一和方便创建的类方法:

    + (item *) findItemRelatedToOtherThing: (Thing *) existingThing inManagedObjectContext *) context {
        item *foundItem = nil;
        // Do NSFetchRequest to see if this item already exists...
        return foundItem;
    }
    
    + (item *) itemWithOtherThing: (Thing *) existingThing inContext: (NSManagedObjectContext *) context {
        item *theItem;
        if( !(theItem = [self findItemRelatedToOtherThing: existingThing inManagedObjectContext: context]) ) {
            NSLog( @"Creating a new item for Thing %@", existingThing );
            theItem = [NSEntityDescription insertNewObjectForEntityForName: @"item" inManagedObjectContext: context];
            theItem.whateverYouWant = existingThing.whateverItHas;
        }
        return theItem; 
    }
    

    现在永远不要直接调用initWithEntity:insertIntoManagedObjectContext:,只需使用您的便利类方法,例如:

    item *newItem = [item itemWithOtherThing: oldThing inContext: currentContext];
    

    【讨论】: