【问题标题】:viewDidLoad and loadView questionsviewDidLoad 和 loadView 问题
【发布时间】:2023-03-25 09:49:01
【问题描述】:

我想测试 viewDidLoad 和 loadView 之间的区别,所以我创建了一个单视图应用程序,然后将 didFinishLaunchingWithOptions 设置为流:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    viewController = [[MyViewController alloc] init];
//    viewController.view.backgroundColor = [UIColor redColor];
    self.window.rootViewController = viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

在我的 MyViewController 的 m 文件中是作为流:

#import "MyViewController.h"

@interface MyViewController ()

@end

@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"%@",self.view);
    self.view.backgroundColor = [UIColor redColor];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)loadView {
    self.view = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
}

@end

但是loadView方法或者viewDidLoad没有被调用,为什么?但是当我在 didFinishLaunchingWithOptions 取消注释时,它们都被调用了。

【问题讨论】:

    标签: ios


    【解决方案1】:

    我只是用简单的例子检查了一下:

    @implementation TestViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        NSLog(@"test");
    }
    
    - (void)loadView
    {
        NSLog(@"load");
    }
    
    @end
    

    而且效果很好:

    2015-08-16 13:18:46.163 Example[51603:406197] load
    2015-08-16 13:18:46.164 Example[51603:406197] test
    2015-08-16 13:18:46.164 Example[51603:406197] load
    2015-08-16 13:18:46.164 Example[51603:406197] test
    

    这里是委托:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    {
        self.window.rootViewController = [TestViewController new];
        [self.window makeKeyAndVisible];
        return YES;
    }
    

    更新 #1

    我忘记了我拥有的默认情节提要。我不使用它,但它是委托中 window 属性初始化所必需的:

    如果您的应用的 Info.plist 需要实现此属性 文件包含 UIMainStoryboardFile 键。幸运的是,Xcode 项目模板通常包括一个综合声明 属性自动为应用程序委托。这个的默认值 综合属性为 nil,这会导致应用创建一个泛型 UIWindow 对象并将其分配给属性。如果您想提供 您的应用程序的自定义窗口,您必须实现 getter 方法 此属性并使用它来创建和返回您的自定义窗口。

    【讨论】:

    • 你可以试试:删除storyboard或者nib,然后运行
    • 我认为更简单的解决方案是使用默认情节提要。我不将 IB 用于 UI,但这让事情变得简单。
    • 问题的关键是 window 不会是 nil 并且 UIViewControllerview 属性是延迟加载。
    • @Bannings 问题的重点是window 属性初始化。
    • @JohnTracid OP有两个问题:1.为什么viewDidLoad没有被调用? 2.为什么viewDidLoad这行不注释viewController.view.backgroundColor = [UIColor redColor];会被调用?
    【解决方案2】:

    "loadView" 在 self.view 被调用并且 self.view 为 nil 时被调用,所以如果你取消注释

    viewController.view.backgroundColor = [UIColor redColor];
    

    您实际上是调用 self.view,然后它会调用(内部)“loadView”,然后是“viewDidLoad”。

    我猜是因为“self.window”没有初始化,“loadView”和“viewDidLoad”没有被调用。

    【讨论】:

      【解决方案3】:

      为什么 viewDidLoad 没有被调用?

      发生这种行为是因为您的窗口为零。所以你的控制器没有显示,它的视图也没有加载。

      试试这个:

      self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
      ViewController *viewController = [[ViewController alloc] init];
      //    viewController.view.backgroundColor = [UIColor redColor];
      self.window.rootViewController = viewController;
      [self.window makeKeyAndVisible];
      

      如果取消注释此行viewController.view.backgroundColor = [UIColor redColor];,为什么会调用 viewDidLoad?

      UIViewController 的视图是延迟加载。如果你取消didFinishLaunchingWithOptions处的注解,虽然你的控制器没有显示,但是你访问了它的view属性,那么视图将被加载然后被丢弃。

      【讨论】:

      • 它成功了。我也找到了。谢谢你的回答。
      • 我可以说当我们使用 self.view 时,如果 view 为 nil 会调用 loadView 方法吗?
      • 你是对的。而viewDidLoad 将在loadView 之后执行。
      猜你喜欢
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      • 1970-01-01
      相关资源
      最近更新 更多