刷新数据后进入前台

在更改默认设置后,我想在AppDelegate中input前景时刷新myViewController的数据。 我做的是

AppDelegate.m

- (void)applicationDidFinishLaunching:(UIApplication *)application { [window addSubview:[navigationController view]]; NSLog(@"APPLICATION DID FINISH LAUNCHING"); // listen for changes to our preferences when the Settings app does so, // when we are resumed from the backround, this will give us a chance to update our UI // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(defaultsChanged:) name:NSUserDefaultsDidChangeNotification object:nil]; } - (void)applicationWillEnterForeground:(UIApplication *)application { /* Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. */ NSLog(@"APPLICATION WILL ENTER BACKGROUND"); [myViewController viewDidLoad]; } 

myViewController.m

 - (void)viewDidLoad { NSLog(@"VIEW DID LOAD IN MY VIEW CONTROLLER"); // watch when the app has finished launching so we can update our preference settings and apply them to the UI [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSettings:) name:UIApplicationDidFinishLaunchingNotification object:nil]; } - (void)updateSettings:(NSNotification *)notif { myLabel.text = @"data has just been modified"; } 

然而,没有什么改变。

你的代码有两个问题。 首先,启动函数(称为执行状态)的顺序似乎对您不清楚,其次您向函数updateSettings添加了一个监听器,但是您从未在上面的代码中调用它,这就是为什么当您的应用启动。

让我先解释一下启动顺序。 当一个应用程序从closures的设备加载时,这些状态会被触发:

 application:didFinishLaunchingWithOptions: applicationDidBecomeActive: 

之后,如果按下主页button,则会触发以下状态:

 applicationWillResignActive: applicationDidEnterBackground: 

然后,如果您再次进入应用程序,则会发生以下情况:

 applicationWillEnterForeground: applicationDidBecomeActive: 

请注意,加载状态仅在第一次加载时发生(但不是在您从主页按下之后)。 现在,对于每个视图,函数viewDidLoad将只被调用一次,这是第一次调用这个视图。 如果再次调用这个视图(在它被加载之后),那么函数viewWillAppear将被调用。 所以通常在viewWillAppear函数中会发生刷新。

我在代码中注意到的一个重要的东西是不正确的,主要的代表函数的使用。 在applicationWillEnterForeground您手动调用了viewDidLoad而不应该这样做,因为如上所述,将自动调用此函数。 另外我看到你正在添加不需要的通知中心。

现在让我们看看代码中的第二个问题。 您正在为viewDidLoad的函数updateSettings添加一个通知中心。 那么这个视图的加载将发生在UIApplicationDidFinishLaunchingNotification事件之后,因此实际上你从来没有调用函数updateSettings 。 此外,由于此function是您class级的成员,因此您无需通知中心即可致电该function。 当我们需要从另一个类中调用某个函数时,我们通常会使用一个通知中心。 简单地说,你需要做的就是直接从viewDidLoad调用这个函数,如下所示:

 [self updateSettings] 

如果您需要在按下主屏幕button后进行更新,请从viewWillAppear调用该function。

我希望这个快速解释可以帮助你。

编辑:在下面回答你的评论

如果你只有一个视图(没有导航控制器…),它第一次出现在内存中,它不会再出现(所以这个函数没有被调用)。 在这里你应该抓住事件UIApplicationDidBecomeActiveNotification所以做到以下几点:

viewDidLoad添加一个通知:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSettings) name:UIApplicationDidBecomeActiveNotification object:[UIApplication sharedApplication]]; 

这将允许函数updateSettings在您每次唤醒应用程序时调用。 另外请记住在最后删除这个监听器:

 [[NSNotificationCenter defaultCenter] removeObserver:self]; 

你的代码有很多问题。

前景和背景之间的混淆

 - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"APPLICATION WILL ENTER BACKGROUND"); ... 

那么,不,它会进入FOREGROUND,并且正在离开BACKGROUND。

在viewDidLoad中缺less超级调用

 - (void)viewDidLoad { ... 

你应该添加一个[super viewDidLoad];

直接调用viewDidLoad

 - (void)applicationWillEnterForeground:(UIApplication *)application { [myViewController viewDidLoad]; ... 

那么,不,不要自己调用viewDidLoad ,因为它应该只被系统调用一次。 超类或子类可能与多个调用不兼容。

不平衡的观察员

 - (void)viewDidLoad { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateSettings:) name:UIApplicationDidFinishLaunchingNotification object:nil]; ... 

通过多次调用viewDidLoad,你实际上注册了同一个事件的多个观察者。 您需要在代码中拥有与removeObserver数量的调用removeObserver addObserver (请注意,您也可以同时删除多个观察者)。

缺less实现?

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(defaultsChanged:) name:NSUserDefaultsDidChangeNotification object:nil]; 

那么,我们没有看到你的defaultsChanged:实现,所以目前还不清楚你试图达到什么目的。 是否将BOOL设置为YES,然后检查该值以确定首选项是否已更改? 类似的东西?

 - (void)defaultsChanged:(id)notif { self.refreshData = YES; } - (void)applicationWillEnterForeground:(UIApplication *)application { if (self.refreshData) { self.refreshData = NO; // we refresh data now ... } }