【问题标题】:loadview getting called infinite timesloadview 被无限次调用
【发布时间】:2013-07-01 12:45:09
【问题描述】:

我的应用程序中有两个 ViewControllers ViewController1.mViewController2.m

AppDelegate 我有这个代码。

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
    self.viewController = [[ViewController1 alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
}
else
{
    self.viewController = [[ViewController1 alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
}


self.window.rootViewController = self.viewController;

[self.window makeKeyAndVisible];

在 ViewController1.m 中,我添加了一个按钮,在单击按钮时,我将显示另一个视图控制器 ViewController2.m,如下所示:

ViewController2 * obj = [[ViewController2 alloc] initWithNibName:nil bundle:nil];

[self.view addSubview:obj.view];

在 ViewController2.m 的 loadView 中,我正在添加另一个像这样的按钮

NSLog(@"\n Load view called");

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[button addTarget:self action:@selector(onButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

[button setTitle:@"Back to previous view" forState:UIControlStateNormal];

button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);

[self.view addSubview:button];

当我运行我的应用程序时,单击 ViewController1.m 中的按钮时,应用程序挂起,并且 ViewController2.m 的 loadView 开始被无限调用。

我不知道这个问题背后的原因,我只是想在单击按钮时加载另一个 ViewController 而我没有使用任何导航控制器。

有人能指出这个问题背后的原因吗?

【问题讨论】:

  • 只要查看方法堆栈跟踪,您就可以轻松找到一次又一次调用loadview的方法或语句

标签: ios uiviewcontroller


【解决方案1】:

不要在loadView 中这样做。而是将您的代码移动到viewDidLoad。问题是您在loadView 中访问self.view,它基本上调用loadView,因为对loadView 的初始调用从未返回。

抱歉绕口令... loadView 在视图尚未实例化时自动调用。只有当它返回时,视图初始化才完成。如果它没有返回并且您尝试访问view 属性,它会再次调用它。在您的情况下,它是递归的,因为您仍在 loadView 方法中。

来自docs

视图控制器在其视图属性被请求但当前为 nil 时调用此方法。此方法加载或创建视图并将其分配给视图属性。

【讨论】:

    【解决方案2】:

    当您使用initWithNibName 时,请勿过度使用loadView。它是一个错误的设计。如果你不想使用viewDidLoad 并且想在初始化阶段做一些事情,那么重写这个方法,

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // write your init code here.
        }
        return self;
    }
    

    【讨论】:

      【解决方案3】:

      loadView 的专属工作是设置 viewControllers 视图属性。可能是这样的

      self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];

      想象一下你的视图属性的 getter 看起来像这样:

       if(!_view)
           [self loadView];
      
        return _view;
      

      这意味着如果你在设置视图之前使用 self.view(就像在 loadView 中一样),loadView 将被一遍又一遍地调用。我的建议通常是避免覆盖 loadView,而是创建一个简单的 configureView 方法,从 awakeFromNibinitWithNib... 调用,以便可以从故事板或 nib 正确创建视图,或通过代码实例化。

      【讨论】:

        猜你喜欢
        • 2010-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-31
        • 1970-01-01
        相关资源
        最近更新 更多