ios – 从AppDelegate调用方法 – Objective-C

前端之家收集整理的这篇文章主要介绍了ios – 从AppDelegate调用方法 – Objective-C前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图从applicationDidEnterBackground方法中的AppDelegate.m调用我的ViewController.m的现有方法,所以我找到了这个链接Calling UIViewController method from app delegate,它告诉我实现这段代码

在我的ViewController.m中

-(void)viewDidLoad
{
    [super viewDidLoad];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    appDelegate.myViewController = self;
}

在我的AppDelegate中:

@class MyViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (weak,nonatomic) MyViewController *myViewController;

@end

在AppDelegate的实现中:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self.myViewController method];
}

所以我把这个代码放在我的项目中,它工作正常,但我不明白代码如何工作,一行一行. sharedApplication有什么作用?为什么我必须设置一个委托而不是只创建一个ViewController实例,如:

ViewController * instance = [[ViewController alloc] init];
[instance method];

解决方法

背景信息(类定义与类实例)

这里重要的概念是类定义和类实例之间的区别.

类定义是类的源代码.例如,ViewController.m包含myViewController类的定义,AppDelegate.m包含AppDelegate类的定义.你问题中提到的另一个类是UIApplication.这是一个系统定义的类,即您没有该类的源代码.

类实例是堆上的一块内存,以及指向该内存的指针.通常使用这样的代码行创建类实例

myClass *foo = [[myClass alloc] init];

请注意,alloc为类的堆保留空间,然后init设置类的变量/属性的初始值.然后将指向实例的指针存储在foo中.

当您的应用程序启动时,会发生以下事件序列(粗略地说):

>系统创建UIApplication类的实例
>指向UIApplication实例的指针存储在某个地方
系统变量
>系统创建AppDelegate类的实例
>指向AppDelegate的指针存储在一个名为的变量中
在UIApplication实例中委托
>系统创建MyViewController类的实例
>指向MyViewController类的指针存储在某处

存储指向MyViewController的指针是事情变得混乱的地方. AppDelegate类有一个名为window的UIWindow属性. (您可以在AppDelegate.h中看到.)如果应用程序只有一个视图控制器,则指向该视图控制器的指针存储在window.rootViewController属性中.但是如果应用程序有多个视图控制器(在UINavigationController或UITabBarController下),那么事情会变得复杂.

意大利面条代码解决方

所以你面临的问题是:当系统调用applicationDidEnterBackground方法时,你如何获得指向视图控制器的指针?好吧,从技术上讲,app委托在窗口属性下的某个地方有一个指向视图控制器的指针,但是没有简单的方法获取该指针(假设该应用程序有多个视图控制器).

另一个线程建议使用意大利面条代码解决问题. (请注意,建议使用意大利面条代码方法只是因为其他线程中的OP不希望正确处理通知.)以下是意大利面条代码的工作原理

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.myViewController = self;

代码检索指向系统创建的UIApplication实例的指针,然后查询delegate属性获取指向AppDelegate实例的指针.然后,指向self的指针(它是指向MyViewController实例的指针)存储在AppDelegate的属性中.

然后,当系统调用applicationDidEnterBackground时,可以使用指向MyViewController实例的指针.

正确的解决方

正确的解决方案是使用通知(如kkumpavat的答案)

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
}

- (void)didEnterBackground
{
    NSLog( @"Entering background now" );
}

-(void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

通过通知,您不会将冗余指针存储到视图控制器,也不必确定系统将指针存储到视图控制器的位置.通过为UIApplicationDidEnterBackgroundNotification调用addObserver,您告诉系统直接调用视图控制器的didEnterBackground方法.

猜你在找的iOS相关文章