簡體   English   中英

iOS CoreData + MoGenerator:僅在使用嵌套上下文時,如何初始化一次托管對象?

[英]iOS CoreData+MoGenerator: How do I initialize a Managed Object once only when I am using nested contexts?

我正在使用生成器從具有TestPerson管理對象的模型生成代碼。 TestPerson從抽象對象TLSyncParent繼承。 在TLSyncParent中,我有以下代碼:

- (void) awakeFromInsert
{
    [super awakeFromInsert];
    QNSLOG(@"%@\n%@", self.managedObjectContext, self.description);
    if (self.syncStatus == nil) {
        self.syncStatusValue = SYNCSTATUS_NEW;
        self.tempObjectPID = [self generateUUID];
        QNSLOG(@"After init values\n%@", self.description);
    }
}

我在其父級為mainMOC,父級為rootMOC的childMOC中創建TestPerson對象。 awakeFromInsert將按預期運行,並進行init更改。 將childMOC保存到mainMOC時,再次運行awakeFromInsert。 從文檔中我不希望這樣,但是有一些歧義。 在文檔中,“您通常使用此方法初始化特殊的默認屬性值。此方法在對象的生存期內僅被調用一次。” 真正的問題是,當awakeFromInsert在mainMOC中運行時,不存在對childMOC進行的init更改。 awakeFromInsert顯然在保存實際發生之前運行。

2013-10-02 11:22:45.510_xctest[21631:303] TestPerson -awakeFromInsert <NSManagedObjectContext: 0xd684780>
<TestPerson: 0xd6863b0> (entity: TestPerson; id: 0xd684ed0 <x-coredata:///TestPerson/t02B71E0D-AE3F-4605-8AC7-638AE072F2302> ; data: {
    dept = nil;
    job = nil;
    objectPID = nil;
    personName = nil;
    syncStatus = 0;
    tempObjectPID = nil;
    updatedAt = nil;
})
2013-10-02 11:22:45.511_xctest[21631:303] TestPerson -awakeFromInsert After init values
<TestPerson: 0xd6863b0> (entity: TestPerson; id: 0xd684ed0 <x-coredata:///TestPerson/t02B71E0D-AE3F-4605-8AC7-638AE072F2302> ; data: {
    dept = nil;
    job = nil;
    objectPID = nil;
    personName = nil;
    syncStatus = 4;
    tempObjectPID = "7AB46623-C597-4167-B189-E3AAD24954DE";
    updatedAt = nil;
})
2013-10-02 11:22:45.511_xctest[21631:303] CoreDataController -saveChildContext: Saving Child MOC
2013-10-02 11:22:45.511_xctest[21631:303] TestPerson -awakeFromInsert <NSManagedObjectContext: 0xd682180>
<TestPerson: 0xd68fce0> (entity: TestPerson; id: 0xd684ed0 <x-coredata:///TestPerson/t02B71E0D-AE3F-4605-8AC7-638AE072F2302> ; data: {
    dept = nil;
    job = nil;
    objectPID = nil;
    personName = nil;
    syncStatus = 0;
    tempObjectPID = nil;
    updatedAt = nil;
})
2013-10-02 11:22:45.511_xctest[21631:303] TestPerson -awakeFromInsert After init values
<TestPerson: 0xd68fce0> (entity: TestPerson; id: 0xd684ed0 <x-coredata:///TestPerson/t02B71E0D-AE3F-4605-8AC7-638AE072F2302> ; data: {
    dept = nil;
    job = nil;
    objectPID = nil;
    personName = nil;
    syncStatus = 4;
    tempObjectPID = "B799AFDA-3514-445F-BB6F-E4FE836C4F9D";
    updatedAt = nil;
})

使用MoGenerator結構時,初始化托管對象的適當位置是什么?

關於awakeFromInsert的文檔有些過時,並且沒有反映嵌套上下文的現實。 當說方法是

當接收方第一次插入到托管對象上下文中時,由Core Data框架自動調用。

它應該真正說出類似“ ..first插入任何托管對象上下文”之類的東西,因為(如您所發現的)這種情況在嵌套上下文中不止一次發生。 實際上,當使用嵌套上下文時, awakeFromInsert的概念已經過時了。 該方法顯然是在過去的非嵌套時代設計的,並且沒有被采用。

有兩種方法可以解決此問題。 一種是簡單的運行時檢查,您可以執行以下操作:

if ([[self managedObjectContext] parentContext] != nil) {
    // Set default values here
}

僅當當前上下文是某些其他上下文的子級時,此代碼才運行。 該方法仍然針對父上下文運行,但是您跳過了默認值設置器。 如果您只嵌套一個級別的深度,那就很好,即,一個父級具有一個或多個子上下文,但沒有父級的“孫子級”上下文。 如果您添加了另一個嵌套級別,那么您將回到起點。

另一個選項(也是我通常更喜歡的一個選項)是將默認值代碼移到單獨的方法中,然后完全不使用awakeFromInsert 也就是說,創建一個名為setDefaultValues類的方法,在您的情況下,該方法將設置syncStatusValuetempObjectPID的值。 在首次創建新實例后立即調用此方法,然后再在其他地方調用 由於它永遠不會得到自動調用,因此除非您告訴它運行,否則該代碼永遠不會運行。

我很確定Mogenerator不會改變您創建托管對象的方式,而只會將實際的托管對象類移動到帶有“ _”前綴的機器生成的文件中,並創建那些托管對象的子類以將所有自定義邏輯放入其中當您重新生成托管對象類時,它不會丟失。

好的,感謝湯姆·赫靈頓,我找到了一種非常好的方法。 它似乎可以最大限度地減少麻煩,而正是我想要的。 它非常適合MoGenerator結構。 我已經使用initWithMO​​C方法在NSManagedObject上創建了一個類別。 我添加了對方法awakeFromCreate的調用,並提供了默認實現。 您只需以覆蓋awakeFromInsert的相同方式覆蓋awakeFromCreate。 唯一的要求就是您始終使用initWithMO​​C方法創建MO。

@implementation NSManagedObject (CoreDataController)

+ (NSManagedObject*) initWithMOC: (NSManagedObjectContext*) context
{
    NSManagedObject* mo = (NSManagedObject*)
            [NSEntityDescription insertNewObjectForEntityForName: NSStringFromClass(self)
                                          inManagedObjectContext: context];

    [mo awakeFromCreate];
    return mo;
}

- (void) awakeFromCreate
{
    return;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM