2012-06-02 91 views
1

更新:請注意,這裏的實際問題不是核心數據更多,而我的強屬性/弱屬性聲明導致對象在新視圖的viewWillLoad和viewDidLoad之間釋放。核心數據多個managedObjectContexts

我正在通過Tim Isted撰寫的關於iOS中的Core Data的書,並且至今一直做得很好。我試圖追蹤新的viewController如何在下面使用第二個managedObjectContext - editingContext - 在保存之前捕獲文本字段中的更改。

- (void)setCurrentPerson:(AWPerson *)aPerson { 
    if(!aPerson) 
    { 
     aPerson = [AWPerson randomPersonInManagedObjectContext:self.editingContext]; 
    } 
    else if([aPerson managedObjectContext] != self.editingContext) { 
     self.title = @"Edit person"; 
     aPerson = (id)[self.editingContext objectWithID:[aPerson objectID]]; 
    } 
    [...] 
} 

此時: aPerson = (id)[self.editingContext objectWithID:[aPerson objectID]]; 當我打印的調試器aPerson說明我應該得到

<AWPerson: 0x6b5de70> (entity: Person; id: 0x6b5bb60 <x-coredata://A6EC85F2-81A8-488F-B2E3-F82687C252A2/Person/p1> ; data: { 
    dateOfBirth = "1973-11-03 12:53:58 +0000"; 
    eyeColor = "(...not nil..)"; 
    firstName = Peter; 
    lastName = Dickens; 
    yearOfBirth = 1973; 

,而不是我得到以下其中<fault>已經取代了價值

<AWPerson: 0x6b609d0> (entity: Person; id: 0x6b5bb60 <x-coredata: 
//A6EC85F2-81A8-488F-B2E3-F82687C252A2/Person/p1> ; data: <fault>) 

我真的看不到發生了什麼事。 aPerson在行之前具有值之前,它們被替換。任何幫助將不勝感激。

謝謝你,史蒂夫

+0

謝謝Jody&Rog。你幫助我更好地理解錯誤,並通過這種方式工作。我仍然努力與具有objectWithId的線,但我會到達那裏。然而,今天我瞭解到強制/弱勢財產申報的重要性。我失去了viewWillLoad和viewDidLoad之間的值。在真正開始理解調試器的幾個小時之後,我追查到一個不正確的屬性聲明 - 提示很多自我厭惡:)這是我將在下次知道的一個。再次感謝,史蒂夫 – Steve

回答

1

我沒有這本書,但我會盡力幫助...

但是,它不看我錯了。它看起來像我期望的(假設aPerson在調用setCurrentPerson時位於不同的上下文中)。我會嘗試瀏覽您發佈的代碼。也許我可以如何確定你的問題,並以某種方式在這個過程中提供答案。我的意見也包含在代碼中,好評如下。

- (void)setCurrentPerson:(AWPerson *)aPerson { 
    if(!aPerson) 
    { 
     // The aPerson object we were given is nil, so get one in the 
     // current editingContext. 
     aPerson = [AWPerson randomPersonInManagedObjectContext:self.editingContext]; 
    } 
    else if([aPerson managedObjectContext] != self.editingContext) { 
     // The aPerson object does not live in editingContext. However, apparently 
     // we want to make sure it lives in the editingContext. Remember, each managed 
     // that has been saved will have a permanent object-id. Any context can use 
     // the object-id to fetch an object into its own ManagedObjectContext. 
     self.title = @"Edit person"; 
     aPerson = (id)[self.editingContext objectWithID:[aPerson objectID]]; 

     // Now, aPerson will point to an object that lives in the MOC editingContext. 
     // However, if it was not previously registered in that MOC, it will be returned 
     // as a fault. This does not mean the object is not there, but this MOC has 
     // not loaded its data. As soon as you cal a method that needs the data, 
     // it will be faulted into memory. 

     // One way, is to access any of its properties. 
     NSLog(@"firstName = %@", [aPerson valueForKey:@"firstName"]); 

     // You can query an object to see if it is a fault. NO means it's 
     // not a fault, and the properties should all be in memory. YES, does not mean 
     // the data is NOT in memory though... it could be in a cache... 

     // You can manually fault the object into memory, but I would 
     // suggest you read all the documentation before using this, because it has 
     // side effects. Consider... 
     if ([aPerson isFault]) { 
      [self.editingContext refreshObject:aPerson mergeChanges:YES]; 
     } 

     // NOTE: In general, you just want the object management system itself 
     // to manage faults. However, if you really want to see that your objects 
     // are what they are supposed to be, you can do any of this to examine them. 
    } 
    [...] 
} 
0

您的代碼沒有任何問題,因爲它是。

A fault是CoreData表示指向存儲中但尚未提取的對象的指針。

這方面主要是出於性能的考慮,一旦您訪問任何Person對象的屬性,即firstNamelastName等Coredata將搜索和檢索商店,實體和您的NSLog描述,然後將匹配你在你的第一個例子中見過。

+0

哦,我剛剛注意到@Jody Hagins已經在他的回答中指出了這一點。 – Rog