如何在后台刷新期间从 AppDelegate.m 访问视图控制器

How do I access a view controller from AppDelegate.m during a background refresh

我正在尝试在我的应用程序中实现后台刷新。我有一个方法 refreshMessages 在我的 UIViewControllers 中(我使用的是 UINavigationController)。我需要从 AppDelegate.m.

访问这个控制器

通常我会这样做:

UINavigationController *navigationController = [self.window.rootViewController navigationController];

获取导航控制器,然后我可以从那里访问它们。但现在肯定行不通了。该应用程序在后台,没有显示 window。关于如何解决这个问题的任何想法?谢谢!

这是我的后台刷新:

-(void)application:(UIApplication *)application
performFetchWithCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {



    NSLog(@"Doing the background refresh");

    UINavigationController *navigationController = [self.window.rootViewController navigationController];
    NSLog(@"Number of controllers is %d", [[navigationController viewControllers] count]);
    //There are zero controllers?!!! Must be because no window is showing
    completionHandler(UIBackgroundFetchResultNewData);



}

是的,你是对的。 window 将是 nil 因为它将不再位于视图层次结构中。

一个厚脸皮的解决方案是通过在其中创建一个 属性 来在 AppDelegate 中保存视图控制器的引用。您可以在应用程序进入后台时通过订阅视图控制器中的相关通知来分配它。

编辑:添加代码

在你的AppDelegate.h

@property (nonatomic, weak) YourViewController *yourViewController;

在YourViewController.m,在viewDidLoad

的某处
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];

appWillResignActive的实现

-(void)appWillResignActive:(id)sender {
    YourAppDelegate *delegate = [UIApplication sharedApplication].delegate;
    delegate.yourViewController = self;
}

在你的完成处理程序中

[self.yourViewController refreshMessages]

此外,请确保在视图控制器被释放后移除观察者。