2011-12-12 91 views
3

我正在編寫一個測試程序,它使用帶有多個選項卡視圖的選項卡控制器。該程序下載多個XML文件,通過Core Data解析並填充sqlite表。 Core Data變量和函數位於Xcode創建的代碼之後的App Delegate文件中。共享託管對象上下文

我開始通過簡單地將managedObjectContext變量傳遞到需要它的每個子視圖中,如我在App代表初始化它,例如:

FirstViewController *vc1; 
vc1 = [[[FirstViewController alloc] initWithNibName:@"FirstView" bundle:nil] autorelease]; 
[vc1 setManagedObjectContext:self.managedObjectContext]; 

然而,我有一個函數(resetData),該刪除整個數據存儲 - 刪除持久性存儲文件,並將所有核心數據變量(managedObjectContext,managedObjectModel,persistentStore等)設置爲零,重新初始化所有內容。這樣程序就可以從頭開始並重新下載網絡中的所有數據。發生這種情況時,子視圖現在指向舊的managedObjectContext。

在所有子視圖中更新managedObjectContext變量的最佳方法是什麼?手動更新resetData函數中子視圖的managedObjectContext變量?使用NSNotificationCenter向所有視圖發送通知?是否完全刪除並重新初始化所有持久性存儲文件過度殺毒?

我現在已經把此getter,只是指回應用程序委託中需要參考MOC的所有類:

- (NSManagedObjectContext *)managedObjectContext { 
    MyAppDelegate* ad = (MyAppAppDelegate*)[[UIApplication sharedApplication] delegate]; 
    return [ad managedObjectContext]; 
} 

我很新的可可/ iOS的設計patters正在嘗試找出做這些事情的最正確方法!我現在有的工作,但我想知道是否有未知的陷阱或未來的問題?謝謝!

+0

」是否完全刪除並重新初始化所有持久性存儲文件過度殺毒?「大概。你可以刪除所有的對象? – jrturton

+0

@jrturton刪除所有對象絕對值得一試。但是如果它們中有很多,它可能會很慢。 CoreData不是數據庫。 – tonklon

+0

@tonklon - 當然。但是從這個問題我們不知道有多少物體。你的回答非常好。重新創建VC堆棧是要走的路 – jrturton

回答

2

恕我直言,經過managedObjectContext到ViewControllers是很好的做法。它使測試更容易,並創建更好的可重用ViewController。

實現所需結果的一種方法是簡單地從商店中刪除所有對象,同時保持CoreData Stack不變。所有視圖控制器都會像以前一樣使用相同的上下文,但它不再包含對象。但這可能會減慢,這取決於對象的數量。

刪除所有對象的最快和最有效的方法實際上是刪除存儲文件。 NSManagedObjectContext爲持久存儲協調器提供了一個setter。您是否嘗試使用新文件創建新storeCoordinator,將其設置爲MOC的storeCoordinator,然後釋放舊協調器並刪除舊文件?您可能需要發送通知,因爲所有ViewController都必須發佈其可能保留的managedObjects。

我剛纔想到的另一個想法是我完全刪除了完整的viewController堆棧,然後使用新的managedObjectContext重新創建它。您可以輕鬆地下載,解析並將新數據保存到其自己的獨立managedObjectContext(具有自己的persistentStoreController和自己的商店)中。一旦完成,從窗口中刪除所有控制器,跟蹤顯示控制器。然後移動新存儲文件覆蓋舊存儲文件,然後重新創建viewController堆棧。雖然這聽起來像是一個昂貴的操作,但事實並非如此。在我的情況下,交換機在用戶界面中甚至不明顯。保留viewControllers的優點在於,舊的managedObjects仍然潛伏在某處,從而導致需要額外編輯的代碼更少。如果你的viewControllers已經按照蘋果公司的建議設置好了,那麼這個開關就會「正常工作」。 「

+0

關於viewController堆棧的有趣想法...我不得不考慮那一點!謝謝 – Raolin

1

工作時使用Singleton模式沒有最好的方式,但良好的實現。您最後一次通過應用程序代理訪問上下文的解決方案很好。請記住,在這種情況下,如果實例變量已被合併,則不能使用該實例變量。

我想你的對象需要知道持久數據何時被重置,因此他們正在使用新的上下文。您可以使用一個實例變量來檢查它:

@synthesize managedObjectContext = moc_ ; 

然後你就可以測試:

- (NSManagedObjectContext *)managedObjectContext { 
    MyAppDelegate* ad = (MyAppAppDelegate*)[[UIApplication sharedApplication] delegate]; 

    if(moc_ != [ad managedObjectContext]) { 
      // NEW CONTEXT. DO ANYTHING NEEDED TO RESET OBJECT 
    } 

    // Use property to change value to ensure set rules (retain for example). 
    [self setManagedObjectContext:[ad managedObjectContext]]; 

    return moc_; 
}