Iphone AppDelegate:是否从ViewController获取值?

Iphone AppDelegate:是否从ViewController获取值?,iphone,objective-c,uiviewcontroller,Iphone,Objective C,Uiviewcontroller,我想去 - (void)applicationWillTerminate:(UIApplication *)application 视图控制器类中的变量。 我已经构建了一个tabbar应用程序,并且只将tabbar控制器添加到appdelegate中 [window addSubview:tabBarController.view]; 如何从TestViewController获取变量: #import <UIKit/UIKit.h> #import <AVFoundati

我想去

- (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
#导入
#进口
@接口TestViewController:UIViewController{
IBUILabel*测试标签;
NSString*currentString;//我要在applicationWillTerminate保存的值
}
@属性(非原子,保留)UILabel*testLabel;
@属性(非原子,保留)NSString*currentString;
@结束

不是100%确定你想要什么,但这里有一个猜测:
UITabBarController有一个名为ViewController的属性,该属性返回与选项卡栏关联的所有视图控制器

假设TestViewController是第一个选项卡,您可以通过以下方式访问它:

- (void)applicationWillTerminate:(UIApplication *)application {
    TestViewController* test_view_controller = [tabBarController.viewControllers objectAtIndex:0] ;
    NSString* value = test_view_controller.currentString ;
}
注意,如果您决定稍后将TestViewController移动到选项卡栏中的其他位置,则此操作将中断

--编辑-- 检查所有控制器并从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.

当您到达applicationWillTerminate时,TestViewController还没有解除锁定,这有点偶然——在应用程序中将该值存储到更高级别可能是有意义的。这种方法是始终将currentString存储在UIApplicationLegate中,这样以后就不必获取它:

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

扩展dbarker的答案,听起来您真正需要的是在数据模型中保存
currentString
值。执行此操作的正确位置是viewController本身

如果您的数据模型只是一个字符串,您可以在应用程序委托中创建一个属性来保存它。然后,每当视图中的
currentString
值发生变化和/或视图关闭时其值发生变化时,viewController就会写入app delegate属性

这样,无论您打开了多少视图,当应用程序关闭时,数据(无论如何,它是应用程序的整个点)始终处于原位

控制器的正确角色是将信息从接口移动到数据模型。严格地说,viewController不应该存储任何超出接口本身所需的数据。这应该是viewControllers通过向数据模型对象发送带有从接口获取的值的消息来设置的数据模型的属性

在这种情况下,视图控制器中不会有
currentString
属性。相反,它们的属性只是对数据模型的
currentString
属性的引用。视图控制器将持续更新该属性,但本身不存储任何内容


这种设计的优点是显而易见的。如果您需要应用程序中的任何位置的值,您可以通过一个位置和一次呼叫来获取该值。除了数据模型之外,应用程序的任何单个部分都不需要知道是否存在应用程序的任何其他部分

这就是我不想看到的,但当我尝试您的代码时,我在关闭应用程序时出现以下错误:**-[UINavigationController currentString]:发送到实例0x4313b80的无法识别的选择器***由于未捕获的异常“NSInvalidArgumentException”终止应用程序,原因:'***-[UINavigationController currentString]:无法识别的选择器发送到实例0x4313b80'它可能位于不同的选项卡索引。您可以对它们进行迭代,并检查其类型是否为TestViewController。NSString*值;对于tabview中的每个控制器,如果([unknownController isKindOfClass:[TestViewController class]]){value=((TestViewController*)unknownController.).currentString;}谢谢,这工作正常,但currentString值每秒都在更改。这可以吗?或者每秒将currentString设置为AppDelegate不太好?这可能不理想-不是因为它是UIApplicationDelegate,而是因为每秒发送三条消息很昂贵(sharedApplication、delegate、setCurrentString)。如果TestViewController可以在关闭时对currentString执行任何需要执行的操作,则可以将其注册为UIApplicationWillTerminateNotification。好的,我重写了代码,因此可以注册UIApplicationWillTerminateNotification并在那里执行操作。谢谢你的提示!