2013-04-14 45 views
0

我的問題是iOS 6選項卡式應用程序。我的工作進行中有5個選項卡,多個選項卡是其他視圖控制器的網關。大多數頁面都需要訪問Model對象,其中包含以數組,字符串等形式存儲的數據。在運行時填充裸骨模型,並且用戶可以在整個應用程序生命週期中添加它。例如,下面列出的代碼來自我的AppDelegate文件,它將一個指針指向裸機模型傳遞給Project View Controller。這工作正常:選項卡應用程序使用導航控制器數組堆棧;因爲我知道Project頁面位於索引2處,所以我可以將模型發送給它。無法在iOS6中的子ViewControllers之間傳遞指針

我的問題與項目頁面的子視圖有關。例如,作爲項目頁面的子視圖,存在(或應該是)用戶處理文件操作的File_IO頁面。 File_IO頁面還需要訪問Model對象。但是,當我嘗試從Project頁面發送Model指針到File_IO頁面時,我以前使用的技術(從AppDelegate到項目)不起作用。我指向FileIO ViewController中的一個空模型。

示例代碼:這是在AppDelegate中,它工作正常:項目視圖控制器中的裸機模型使用數據填充。

 //To the Project View Controller... 
UINavigationController *project_NavigationController = 
[[tabBarController viewControllers] objectAtIndex:2]; 
Project_ViewController *project_ViewController = 
[[project_NavigationController viewControllers] objectAtIndex:0]; 
//This hides the navigation bar on the project page but it also removes the bar on any subsequent pages! They need to be programmmatically reset in ViewDidLoad. 
[project_NavigationController setNavigationBarHidden:YES animated:YES]; 
project_ViewController.currentGeoModel = newGeoModel; 

現在,我的Project_ViewController嵌入在NavigationController並有4個個子ViweControllers。一個名爲FileIO_ViewController。我想將CurrentModel從Project_ViewController傳遞給FileIO_ViewController。在 - (void)viewDidLoad方法下,我嘗試了一些不起作用的東西。例如,

UINavigationController *project_NavigationController = (UINavigationController *) self.presentedViewController; 
FileIO_ViewController *fileIO_ViewController = [[project_NavigationController viewControllers] objectAtIndex:1]; 
fileIO_ViewController.currentModel = currentModel; 

編譯,但是當我嘗試訪問FileIO_ViewController方法內的currentModel時,它是空的。

如果任何人都可以花時間幫忙,我會非常感激。對我來說最好的答案是以一個明確的代碼示例的形式,顯示如何將指針傳遞給像我的模型這樣的對象,從ViewController到另一個ViewController,而您並不明確知道子VC所處的堆棧位置。 (在我的例子中,我使用索引1,但實際上我並不知道FileIO_ViewController在哪個索引中生存,因爲我在Project_ViewController下有三個其他ViewController。我試過了幾個整數,但沒有成功。)

如果你確實回答了這個問題,當談到iOS 6時,請考慮我是一個新人,而目標C--爬山蘋果已經很長時間了,而且我還沒有接近頂級呢!

感謝

蒂姆·雷德菲爾德 挪威

+0

整個應用程序中是否存在單個模型對象,或者是否有多個單獨實例化的對象傳遞? – foundry

+0

故事板,xib或全部代碼? – foundry

回答

-1

如果您有您的應用程序共享的單一模式,你不應該主動傳遞指針周圍,你應該使模型可以從一個位置,離開它可以讓個別對象在需要時訪問相同的模型。您的模型指針的一個好位置在您的應用程序委託中。

在appDelegate的。.h文件,聲明屬性模型:

//appDelegate.h 

    @property (nonatomic, strong) MyAppModel* appModel; 

後您實例中的appDelegate模型,只需將其分配給屬性:

//appDelegate.m 

    - (BOOL)application:(UIApplication *)application 
      didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.appModel = [[MyAppModel alloc] init]; 
    //set up bare-bones appModel here 
    return YES; 

}

然後你可以訪問此財產從任何viewController需要模型數據,因此:

#import appDelegate.h; 

AppDelegate* appDelegate = [UIApplication sharedApplication] delegate; 
MyModel* model = appDelegate.model 

(更好,使模型對象到它自己的Singleton object,但使用的appDelegate將讓你開始)

如果需要是傳遞模型,那麼你需要照顧,你是將它們傳遞給合適的對象。這是你現有的代碼破壞的地方。例如,您對NavigationController堆棧的結構做出了許多假設。但每當你移動下一個堆棧通過彈出控制器關閉頂部,你完全失去除此之外控制器實例。當你通過堆棧向前返回到那個控制器時,實際上會創建一個新的實例(除非你已經注意保持一個指針掛起來並確保按下這個指針)。如果您需要在這方面更多的幫助,你需要準確地描述你的應用程序的佈局,以及如何創建您的viewControllers,navigationController棧等

更新(以下您的意見)

如果對模型的變化是整個應用有效的,那麼我不明白爲什麼你不能只是訪問模式時,你需要從無論你碰巧在通過appDelegate.model的應用。如果你有版本的這個模型,你可以看看如何創建一個singleton數據管理器對象,它可以處理存儲模型數組(或模型歷史記錄)的詳細信息,並根據請求提供正確的模型。原理是一樣的 - 而不是主動將模型對象傳遞給viewControllers,讓他們根據需要從中央源請求數據。

關於你的描述「現在,我的Project_ViewController被嵌入到一個NavigationController中,並有4個子ViewControllers。」,我不認爲你已經完全理解了Classes,Storyboard場景和實例之間的區別。

你在你的故事板的一部分,這種安排:

UINavigationController 
     |     push      push      push 
     |->UIViewController1 -----> UIViewController2 -----> UIViewController3 -----> 
          segue     segue     segue 

您談談通過訪問NavController的堆直接從VC1(說)將數據傳遞到VC3。

您需要考慮的是,故事板描述了一個模板,顯示實例化時實例將如何相互關聯。它們是而不是僅僅因爲故事板被加載而被實例化。當你到達VC1時,能夠在VC2和VC3之間切換到模板中,但在啓動切換之前,VC2和VC3都不存在 - 作爲實例。 segue進程實例化它的destinationViewController因此,將數據從VC1直接傳遞到VC3是沒有意義的。當你在VC1時,navController的堆棧只包含一個項目(一個VC1實例);當您繼續使用VC2時,它將包含VC1和VC2的實例,並且只有當您實際向VC3延續時,實例纔會創建並放入堆棧。

通過步進代碼:

UINavigationController *project_NavigationController = 
          (UINavigationController *) self.presentedViewController; 

presentedViewController屬性可modal塞格斯,那就是你有一個呈現,並且呈現視圖控制器。另一方面,NavControllers使用push segues(因爲它們將child viewControllers推到它們的viewControllers堆棧上,這是您可以從中獲取指針的地方)。

在這種情況下,self.presentedViewController是零,你正在分配給一個新的變量。該代碼什麼都不做,但編譯器不會抱怨。

FileIO_ViewController *fileIO_ViewController = 
        [[project_NavigationController viewControllers] objectAtIndex:1]; 

project_NavigationControlle是零,所以它的屬性都是零。 fileIO_ViewController獲取零。 同樣在最後一行,你發送一條消息給nil,這不是一個錯誤,而是多餘的。

+0

感謝您的評論,這給了我一個想法如何前進。我沒有名譽點,所以我無法讚揚你!爲了澄清,我實際上已經在AppDelegate中實例化了對象currentModel,但是這是一種情況,用戶可能希望在程序的其他部分向該currentModel添加數據,並且可能希望用包含舊模型的新模型替換currentModel不同的數據。所以我想在FileIO頁面中啓用它。除了小代碼生成的按鈕外,佈局幾乎完全位於故事板和xib中;沒有代碼生成的ViewControllers。 – user1976727

+0

@ user1976727,看我更新的答案。你可能無法從-1(?!)提高我的分數,但你可以考慮打勾... – foundry

+0

謝謝,我沒有意識到滴答位,我只是這樣做(我想!我假設這意味着檢查綠色的勾號?)。您的原始答案適用於我,所以我認爲這是一個解決方案,如果有幫助。更新的答案更好,謝謝! – user1976727

相關問題