首先,我说过我搜索过Google,尽管其中许多问题都类似,但以下异常行为和补救措施却一无所获。

我已经创建了一个UIViewController以及与几个IBOutlet相关的笔尖。在尝试从另一个类中使用该笔尖时,我发现在用initWithNibName:bundle:实例化它之后,IBOutlets仍然为零。

我确认它们已正确连接,是的,它们正在合成中,但仍然没有。在进一步调查时,我将initWithNibName方法更改如下:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

        UIView *view = self.view;
        NSArray *subviews = self.view.subviews;
        NSLog(@"Loaded view containing %d subviews.", [subviews count]);

    }
    return self;
}


令人难以置信的是,这里增加了三行,创建了可抛弃的变量和日志记录,这使得IBOutlet可以正确连接并从外部工作。

我已经清理,重建并重新启动了计算机,但是,如果我删除了这些行,它将停止工作。我在这里真的很困惑,担心我的伏都教工作会在我运送的那一刻中断。关于可能发生的事情有什么想法吗?

最佳答案

您会误解initWithNibName:bundle:的功能以及UIViewController何时装入其笔尖。

initWithNibName:bundle:方法记录要加载的笔尖的名称。它不会立即加载笔尖。

-[UIViewController view]方法通过按需发送[self loadView]来按需加载笔尖。 -[UIViewController view]的实现基本上是这样的:

- (UIView *)view {
    if (_view == nil) {
        [self loadView];
        [self viewDidLoad];
    }
    return _view;
}


因此,如果在self.view覆盖中调用initWithNibName:bundle:,将导致视图控制器加载其笔尖。

但是,通常不适合从self.view调用initWithNibName:bundle:。视图控制器应该能够不存在视图层次而存在。

例如,假设一个用户正在运行您的应用程序并浏览多个视图控制器,您可以通过将视图控制器推到导航控制器上来实现这些视图控制器。然后,用户会切换到另一个应用程序一段时间。现在,系统内存不足,因此它杀死了后台应用程序-包括您的应用程序。

当用户再次启动您的应用程序时,您的应用程序(如果做得很好)应尝试恢复用户的状态。这意味着将推送视图控制器堆栈重新加载到导航控制器中。但是,只有顶视图控制器的视图在屏幕上可见。立即为所有隐藏的视图控制器重新加载视图会浪费时间,内存和电池。这就是每个视图控制器按需加载其笔尖的原因。

关于objective-c - 在initWithNibName:bundle期间创建一次性变量时,未设置IBOutlets:,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13593395/

10-11 17:24