刷新数据后进入前台
在更改默认设置后,我想在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 ... } }