在没有 nibs/xibs 的情况下正确使用 loadView 和 viewDidLoad 与 UIViewController

发布于 2024-12-27 07:46:59 字数 1775 浏览 1 评论 0原文

当我在没有笔尖的情况下编程时,我的印象是我需要调用 loadView 来初始化我的视图,如下所示:(

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        // Custom initialization
        [self loadView];
    }
    return self;
}

我设置了 nibNameOrNil = nil,因为没有笔尖。)

然后,我设置了视图,就像this:

- (void) loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 367)];
    [self viewDidLoad];
}

这是 viewDidLoad 中执行的所有其他操作。

我仍然不确定是否应该以这种方式调用 loadView 和 viewDidLoad 。他们不会自动被呼叫。

令人困惑的是 UIViewController 类参考的文档:

loadView讨论

您永远不应该直接调用此方法。视图控制器调用 当请求视图属性但当前为 nil 时使用此方法。 如果您手动创建视图,则必须重写此方法并 使用它来创建您的视图。如果您使用 Interface Builder 来创建 你的视图并初始化视图控制器——也就是说,你初始化 使用 initWithNibName:bundle: 方法的视图,设置 nibName 和 直接 nibBundle 属性,或创建您的视图和视图 Interface Builder 中的控制器 - 那么您不能覆盖它 方法。

所以,如果我不应该直接调用 loadView,我就不明白如何调用它。

此方法的默认实现会查找有效的笔尖 信息并使用该信息加载关联的 nib 文件。 如果未指定笔尖信息,则默认实现创建 一个普通的 UIView 对象并使其成为主视图。

我不明白它是如何工作的——创建一个痛苦的 UIView。

如果您重写此方法以手动创建视图, 您应该这样做并将层次结构的根视图分配给 查看属性。 (您创建的视图应该是唯一的实例,并且 不应与任何其他视图控制器对象共享。) 此方法的自定义实现不应调用 super。

如果您想对视图执行任何其他初始化,请执行以下操作 所以在viewDidLoad方法中。在 iOS 3.0 及更高版本中,您还应该 重写 viewDidUnload 方法以释放对 视图或其内容。

好了,到目前为止还没有说viewDidLoad是如何调用的。所以对于viewDidLoad:

viewDidLoad 讨论

此方法在视图控制器加载其后调用 相关视图存入内存。 无论什么情况都会调用此方法 视图是否存储在 nib 文件中或创建 以编程方式在 loadView 方法中。这种方法最常用 用于对视图执行额外的初始化步骤 从 nib 文件加载。

被什么叫?

由于这些方法不会在我的代码中自动调用,因此我认为我必须自己调用它们。但我仍然没有从文档中清楚地理解这是正确的做法。

When I program without a nib, I am under the impression that I need to call loadView to initialize my view, like this:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        // Custom initialization
        [self loadView];
    }
    return self;
}

(I have set nibNameOrNil = nil, since there is not nib.)

Then, I set up the view, like this:

- (void) loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 367)];
    [self viewDidLoad];
}

This is do everything else in viewDidLoad.

I'm still unsure if I am supposed to make the calls to loadView and viewDidLoad in this way. They are not getting called automatically.

What is confusing is in the documentation for the UIViewController class reference:

loadView Discussion

You should never call this method directly. The view controller calls
this method when the view property is requested but is currently nil.
If you create your views manually, you must override this method and
use it to create your views.
If you use Interface Builder to create
your views and initialize the view controller—that is, you initialize
the view using the initWithNibName:bundle: method, set the nibName and
nibBundle properties directly, or create both your views and view
controller in Interface Builder—then you must not override this
method.

So, I don't understand how loadView gets called if I should never call it directly.

The default implementation of this method looks for valid nib
information and uses that information to load the associated nib file.
If no nib information is specified, the default implementation creates
a plain UIView object and makes it the main view.

I don't understand how that works -- the creation of a pain UIView.

If you override this method in order to create your views manually,
you should do so and assign the root view of your hierarchy to the
view property. (The views you create should be unique instances and
should not be shared with any other view controller object.) Your
custom implementation of this method should not call super.

If you want to perform any additional initialization of your views, do
so in the viewDidLoad method. In iOS 3.0 and later, you should also
override the viewDidUnload method to release any references to the
view or its contents.

Okay, so far it doesn't say how viewDidLoad is called. So for viewDidLoad:

viewDidLoad Discussion

This method is called after the view controller has loaded its
associated views into memory. This method is called regardless of
whether the views were stored in a nib file or created
programmatically in the loadView method. This method is most commonly
used to perform additional initialization steps on views that are
loaded from nib files.

Called by what?

Since These methods are not getting called automatically in my code, I am left to think that I have to call them myself. But I still don't get a clear understanding form the documentation that this is the right thing to do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷…雨湿花 2025-01-03 07:46:59

正如文档所述,您不应该自己调用这些方法。

这是如何工作的,UIKit 的代码将在实际需要在屏幕上呈现该控制器的视图层次结构时调用您的 loadView 方法。

具体来说,如果任何代码尝试读取视图控制器上的 view 属性,并且该属性为 nil,则 UIViewController 的代码将调用 loadView 方法。如果您自己不实现 loadView ,那么默认实现将回退到尝试从 nib 加载视图层次结构。

当您尝试呈现视图控制器并且视图为零时,这一切都会自动发生。 (如果您的视图控制器必须卸载其视图以响应内存压力,则在您的应用程序运行时,这种情况可能会发生多次,这是您“免费”获得的另一种行为,并且您不想调用自己)

如果这些方法不是在视图控制器中被调用,那么您呈现此视图控制器的方式一定有问题,这会阻止 UIViewController 中的框架代码调用这些方法。发布该代码,有人可以帮助您找出该错误。

不过,在尝试修复错误之前,您应该从代码中删除这些错误:

[self loadView]
[self viewDidLoad]

然后在您自己的viewDidLoad实现中,您将需要调用超类的实现与 [super viewDidLoad]

记住,在 loadView 中,您唯一的责任是将 self.view 设置为某个有效视图。就是这样。然后,UIKit 代码将看到这一点并为您调用 viewDidLoad

希望有帮助。

As the documentation says, you should not call these methods yourself.

How this is meant to work is that UIKit's code will call your loadView method if and when it actually needs to present that controller's view hierarchy on screen.

Specifically, if any code attempts to read your view property on your view controller, and that property is nil, then UIViewController's code will call the loadView method. If you don't implement loadView yourself, then the default implementation will fall back to attempting to load the view hierarchy from the nib.

This all happens automatically when you attempt to present your view controller and the view is nil. (This can happen multiple times while your app is running if your view controller has to unload its view in response to memory pressure, another behavior you get for 'free' and that you don't want to call yourself)

If these methods are not being called in your view controller, then there must be something wrong with how you are presenting this view controller, which is preventing the framework code in UIViewController from calling these methods. Post that code and someone can help you figure out that bug.

Before you attempt to fix that bug, though, you should remove these from your code:

[self loadView]
[self viewDidLoad]

And then in your own implementation of viewDidLoad, you will want to call the superclass' implementation with [super viewDidLoad]

Remember that in loadView your only responsibility to set self.view to some valid view. That's it. UIKit code will then see that and call viewDidLoad for you.

Hope that helps.

聊慰 2025-01-03 07:46:59

Firoze Lafeer 的答案是正确的,我只是想展示如何以正确的方式强制加载视图属性:

(void)self.view;

你不应该这样做!如果你必须这样做,你就做错了什么,但不要自己调用 -loadView-viewDidLoad任何情况。

The answer by Firoze Lafeer is correct, I just want to show how to force load the view property the correct way:

(void)self.view;

You should not do this! If you must, you are doing something wrong, but do not call -loadView and -viewDidLoad yourself at any circumstances.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文