2010-02-15 166 views
1

我想在AppDelegate:從ViewController獲取價值?

- (void)applicationWillTerminate:(UIApplication *)application 

從視圖控制器類來獲得一個變量。 我已經構建了一個tabbar應用程序,並只將tabbar控制器添加到appdelegate。

[window addSubview:tabBarController.view]; 

我怎樣才能得到一個變量從TestViewController:

#import <UIKit/UIKit.h> 
#import <AVFoundation/AVFoundation.h> 

@interface TestViewController : UIViewController { 
    IBOutlet UILabel *testLabel; 
    NSString *currentString; //Value that i want to save at applicationWillTerminate 
} 

@property (nonatomic, retain) UILabel* testLabel; 
@property (nonatomic, retain) NSString* currentString; 

@end 

回答

2

這有點意外的是TestViewController沒有被你達到applicationWillTerminate時間dealloc'd - 它可能是有意義的水平更高的存儲在您的應用程序的價值。這種方法將總是存儲currentString在UIApplicationDelegate,這樣你就不必在以後獲取它:

@implementation TestViewController 
- (void)setCurrentString:(NSString *)currentString { 
    ((MyAppDelegate *)[[UIApplication sharedApplication] delegate]).currentString = currentString; 
} 
@end 
+0

感謝這工作正常,但currentString值每秒都在變化。這是好的,還是不是很好,每秒設置currentString到AppDelegate? – x2on

+2

它可能並不理想 - 不是因爲它是UIApplicationDelegate,而是因爲每秒發送三條消息都很昂貴(sharedApplication,Delegate,setCurrentString)。如果TestViewController可以在關閉時執行任何需要處理currentString的操作 - 您可以將其註冊爲UIApplicationWillTerminateNotification。 – dstnbrkr

+0

好吧,我重寫了我的代碼,所以我可以註冊UIApplicationWillTerminateNotification並在那裏執行操作。感謝這個提示! – x2on

0

不是100%確定你所要求的,但這裏有一個猜測:
的UITabBarController的有一個屬​​性叫viewControllers其中全部歸還視圖控制器與標籤欄關聯。

假設TestViewController是你可以用得到它的第一個標籤:

- (void)applicationWillTerminate:(UIApplication *)application { 
    TestViewController* test_view_controller = [tabBarController.viewControllers objectAtIndex:0] ; 
    NSString* value = test_view_controller.currentString ; 
} 

注意,如果你決定以後TestViewController移動到的TabBar不同的位置,這將打破。

- 編輯 - 檢查所有控制器並從類型爲TestViewController的控制器獲取字符串。

NSString* value = nil ; 
for (id unknownController in tabBarController.viewControllers) { 
    if ([unknownController isKindOfClass:[TestViewController class]]) { 
    value = ((TestViewController*)unknownController).currentString ; 
    } 
} 
// value should be the value of the string. 
+0

這是我wan't,但是當我嘗試你的代碼中,我得到了如下因素錯誤,當我關閉應用程序: *** - [UINavigationController的currentString]:無法識別的選擇發送到實例0x4313b80 ***終止應用程序由於未捕獲的異常'NSInvalidArgumentException',原因:'*** - [UINavigationController currentString]:無法識別的選擇器發送到實例0x4313b80' – x2on

+0

它可能在不同的標籤索引處。你可以遍歷它們並檢查它的類型TestViewController。 NSString * value;如果([unknownController isKindOfClass:[TestViewController class]]){ value =((TestViewController *)unknownController).currentString; } – Eld

1

擴展在dbarker的回答,這聽起來像你真正需要的是保存在currentString值的數據模型。 viewController本身就是這樣做的適當位置。

如果您的數據模型只是一個字符串,您可以在應用程序委託中創建一個屬性來保存它。然後,當視圖關閉時,只要視圖中的currentString值發生變化和/或其值,視圖控制器就會寫入應用程序委託屬性。

這樣,無論您打開多少個視圖,數據(無論如何都是應用程序的整個點)始終處於關閉狀態。

控制器將信息從接口移動到數據模型的角色是正確的。嚴格地說,viewController不應該存儲超出界面本身需要的數據。這應該是viewController通過使用從接口獲取的值向消息模型對象發送消息而設置的數據模型的屬性。

在這種情況下,您的視圖控制器中不會有currentString屬性。相反,它們的屬性只是對數據模型的currentString屬性的引用。視圖控制器將不斷更新該屬性,但不會自己存儲任何內容。

這種設計的優點是顯而易見的。如果您需要應用程序中的任何位置的值,則只需一個位置和一個電話即可獲取。除了數據模型之外,應用程序的任何部分都不需要知道應用程序的任何其他部分的存在。