如何在AppDelegate的applicationDidEnterForeground中调用UIViewController方法(OC)
iOS Objective-C:从AppDelegate/SceneDelegate调用ViewController方法
核心问题说明
iOS 13及以后版本引入多场景架构,UIApplicationDelegate的applicationDidEnterForeground:方法可能不会触发,实际开发中更多使用UISceneDelegate的sceneWillEnterForeground:方法。两种场景的实现逻辑类似,下面分别给出示例。
方法一:使用通知中心*(推荐,低耦合)*
这种方式无需让AppDelegate/SceneDelegate直接持有ViewController引用,通过发送通知触发目标方法,是灵活性最高的实现方案。
1. 在ViewController中注册通知
在viewController.m的viewDidLoad里注册监听应用进入前台的通知:
#import "viewController.h" @interface viewController () @end @implementation viewController - (void)viewDidLoad { [super viewDidLoad]; // 注册系统自带的前台通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAppEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; } // 应用进入前台时执行的自定义方法 - (void)handleAppEnterForeground { NSLog(@"应用进入前台,执行ViewController内的逻辑"); // 这里写入你需要触发的业务代码 } // 销毁时移除通知,避免内存泄漏 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end
2. 触发通知(无需额外代码)
- 若用AppDelegate:系统会在
applicationDidEnterForeground:执行时自动发送UIApplicationWillEnterForegroundNotification通知,ViewController会自动接收并触发方法。 - 若用SceneDelegate(iOS 13+):系统会在
sceneWillEnterForeground:执行时发送该通知,无需额外操作。
如果需要自定义通知场景,可在对应方法中手动发送:
// AppDelegate.m - (void)applicationDidEnterForeground:(UIApplication *)application { // 发送自定义通知(可选) [[NSNotificationCenter defaultCenter] postNotificationName:@"CustomAppForegroundEvent" object:nil]; }
此时ViewController中注册对应自定义通知即可。
方法二:直接获取ViewController引用*(不推荐,高耦合)*
通过获取当前窗口的根ViewController或导航栈顶层ViewController直接调用方法,但这种方式依赖页面层级结构,后续调整页面时需同步修改代码,维护成本高。
示例:在AppDelegate中调用
#import "AppDelegate.h" #import "viewController.h" @implementation AppDelegate - (void)applicationDidEnterForeground:(UIApplication *)application { // 获取根ViewController UIViewController *rootVC = self.window.rootViewController; // 判断是否为目标ViewController if ([rootVC isKindOfClass:[viewController class]]) { viewController *targetVC = (viewController *)rootVC; [targetVC handleAppEnterForeground]; } // 若ViewController在导航栈中,获取顶层VC // UINavigationController *nav = (UINavigationController *)self.window.rootViewController; // viewController *targetVC = (viewController *)nav.topViewController; // if ([targetVC isKindOfClass:[viewController class]]) { // [targetVC handleAppEnterForeground]; // } } @end
关键提示
- iOS 13+优先使用
SceneDelegate的sceneWillEnterForeground:方法,多场景应用中AppDelegate的生命周期方法可能失效。 - 通知中心是解耦的最佳方案,可避免组件间强依赖。
- 无论哪种方式,都要确保ViewController已加载且不为空,避免空对象调用导致崩溃。
内容的提问来源于stack exchange,提问作者user4826471
相关产品推荐
相关产品推荐

