2011-03-03 20 views
1

我有一個簡單的iOS應用程序,在UINavigationController下有一個UIViewController。 UIViewController有一個NSManagedObjectContext的IBOutlet。如何通過Interface Builder的XIBs傳遞NSManagedObjectContext

AppDelegate具有用於導航控制器的IBOutlet - 但不是視圖控制器。視圖控制器會自動實例化XIB進程(作爲導航控制器的子項)。

使用此設置,如何幹淨地將應用程序委託的NSManagedObjectContext分配或傳遞給視圖控制器的IBOutlet屬性。有一個導航控制器的方式:)和應用程序委託沒有UIViewController的直接屬性。

這是一個奇怪的問題,我想將一個屬性從一個XIB組件鏈接到另一個組件的屬性。我所做的大部分XIB工作都需要一個屬性,然後將它指向XIB中的一個對象,然後將其實例化爲正常流程,但在這種情況下,上下文在應用程序委託中正確創建,我只想在實例化時將其傳遞給視圖控制器。

+0

我認爲還值得考慮一個具有9個視圖控制器的應用程序 - 在不同時間使用 - 所有這些都需要訪問託管上下文。在某些情況下,view-A和view-C需要上下文,但是view-B不需要。簡單地將它傳遞給每個視圖控制器的幼稚方法似乎很麻煩。這是否意味着view-A使用上下文創建view-B(即使view-B不需要它),以便view-B可以創建view-C並將它傳遞給它?我發現這使得我的愚蠢的視圖控制器太聰明,應用程序不靈活。 – 2011-03-03 19:58:47

回答

0

你並不需要通過它,只是從應用程序的委託抓住它要求:

#import "MyAppDleegate.h" 

NSManagedObjectContext* moc = [(MyAppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext]; 
+0

這是一種方法(實際上是一種非常實用的方法),但在某種程度上,它將上下文硬編碼爲視圖本身。我喜歡它顛倒設置,但作爲一個單例,它違反了「依賴注入」的原則。例如,單元測試這個特定的視圖控制器是很困難的,因爲它會繼續向UIApplication和AppDelegate提供它所需要的資源。理想的解決方案是在運行時將視圖「提供」給視圖控制器,訣竅在於將它連接到ala IB。 – 2011-03-03 20:06:27

+0

True - 在有多個線程訪問託管對象的某些應用程序中,我使用了NSManagedObjectContext上的一個類別,它根據需要創建moc,使用線程名稱作爲標識符 - 然後將它們存儲在字典中,線程名稱爲key 。顯然你必須命名所有線程,並斷言你是否從一個未命名的線程獲得請求。這是關於使用IB的最後一件事情,我喜歡XCode 4現在建立連接的方式,但是不得不發現像傳遞一個moc這樣的技巧是非常令人憤怒的。 – 2011-03-03 23:45:35

0

蘋果的文檔建議您傳遞給你的管理對象範圍內引用類的要求他們,而不是引用它從您的應用程序委託。

這是application:didFinishLaunchingWithOptions:在我的一個Core Data項目中的樣子。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{   
    LocationsViewController *lvc = (LocationsViewController *)self.navigationController.topViewController; 
    lvc.managedObjectContext = self.managedObjectContext; 
    assert(lvc.managedObjectContext != nil); 
    [self.window addSubview:self.navigationController.view]; 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 

你會看到我也從一個帶有單個根視圖控制器的UINavigationController開始。

+0

謝謝馬克。不幸的是,我沒有參考我的應用程序委託中的主視圖控制器 - 只是導航控制器。 – 2011-03-03 19:53:53

+0

但是,您已將Interface Builder中的主視圖控制器設置爲導航控制器的根視圖控制器。只要讓導航控制器返回它的頂視圖控制器。在您的視圖控制器上爲NSManagedObjectContext設置一個公共屬性。使用AppDelegate中的'self.managedObjectContext'在視圖控制器上設置'managedObjectContext'屬性。 – 2011-03-03 20:49:54

+0

是的,我可以做到這一點 - 但正在尋找一種方法在Interface Builder的XIB中完成它。我有9個其他視圖控制器不在導航堆棧上,也需要託管的對象上下文,我也想將它應用於這些。 – 2011-03-03 21:06:16

0

你有正確的想法,但你摔跤的問題似乎完全是你自己的創作。你說你的應用程序委託有一個導航控制器的出口,但不是導航控制器的根視圖控制器,因爲你已經設置了你的筆尖,以便在加載筆尖時創建視圖控制器。這沒什麼不妥,但也沒有理由說應用程序代表不應該爲該控制器設置插座。事實上,網點的全部理由是要獲得從筆尖加載的東西的參考。

爲您的根視圖控制器的應用程序委託添加一個插座,並將其連接。然後,應用程序委託可以爲控制器提供對託管對象上下文的引用。

關於您關於多個視圖控制器的問題,我想知道什麼樣的真實世界的應用程序可能具有需要數據的視圖控制器(A),加載不需要任何數據的另一個視圖控制器(B)然後是第三個(C),這又需要數據?一個現實的例子可能會有所幫助,如果有的話。

請記住,您不必將整個託管對象上下文傳遞給每個連續的視圖控制器。您可以通過傳遞託管對象來傳遞控制器需要完成工作的模型部分。

相關問題