用你自己的initWithFrame初始化一个类是否可以?

时间:2011-07-16 01:56:03

标签: ios objective-c

我正在将iPhone应用转换为通用应用。我有一个NIB视图,我想在iPad上使用,但调整大小和定位。在iPhone上我正在使用initWithNibName正常初始化...

 EventEditViewController *eventEditViewController = [[EventEditViewController alloc] initWithNibName:@"EventEditViewController" bundle:nil];

我发现由于各种原因,这对我来说在iPad上效果不佳。所以我创建了自己的初始化方法,以便在iPad上运行时调用...

EventEditViewController *eventEditViewControllerForIPad = [[EventEditViewController alloc] initWithFrame:iPadFrame eventDate:longDate event:eventName delegate:self];

这解决了一些问题。一个如何调整视图的大小和位置,以及如何正确初始化某些变量。我实际上传递的变量多于你在这里看到的变量。

它工作得很好,但我现在注意到,与initWithNibName不同,viewDidLoad在我的initWithFrame方法之前触发。我只发现了这个,因为我试图在viewDidLoad中访问的变量显示为僵尸,我以为我是在initWithFrame方法中初始化它。

我对这种行为感到惊讶。这是正常的吗?我认为视图将在alloc / init调用中的命名initMethod之前加载。

我现在想知道我在做什么可能不是一件好事。就像我说它工作得很好,但我不应该在这里使用我自己的初始化方法吗?

如果可以这样做,也许有人可以解释为什么视图在init方法之前加载。

谢谢,

约翰

3 个答案:

答案 0 :(得分:2)

如果您的-initWithFrame:...方法正在访问视图控制器的view属性,则在init方法完成之前将调用-viewDidLoad,因为view访问器将导致视图为加载。

至于是否可以使用自己的方法,只要你的init方法调用类的指定初始值设定项就可以了。

答案 1 :(得分:1)

初始化成员变量应该在viewDidLoad或awakeFromNib中完成。 awakeFromNib是第一个在视图从Xib生效时调用的方法。

首选使用viewDidLoad为大型数组分配内存,因为您可以在viewDidUnload中释放它们。

当其他视图需要更多内存时,导航控制器和标签栏控制器都使用视图加载方法来卸载视图。

应尽可能避免分配任何其他方法。

答案 2 :(得分:1)

来自Apple的PageControl源代码

// load the view nib and initialize the pageNumber ivar
- (id)initWithPageNumber:(int)page
{
    if (self = [super initWithNibName:@"MyView" bundle:nil])
    {
        pageNumber = page;
    }
    return self;
}

您可以在EventEditViewController中定义自己的自定义init方法,并且可以使用上面的自定义方法初始化viewController,并根据需要设置任意数量的成员变量,如iPadFrame,longDate,eventName等。

请确保您完全按照上述方式调用它,因为在此类自定义init方法中调用超级实现非常重要。

另外,为了更好地说明你应该释放在viewDidLoad方法中创建的数组的位置,除了viewDidUnload之外,它首先是dealloc方法。这背后的原因是viewDidUnload方法并不总是被调用。仅在应用程序开始接收内存警告时才会调用它。与此相比,dealloc方法在释放初始化的viewController时会自动被调用,并且它的保留计数达到0.你应该在dealloc方法中释放初始化viewDidLoad方法和其他保留属性的数组。

还要记住,当应用程序收到内存警告时,它实际上是释放额外内存的机会。此外,为内存中的所有viewControllers调用viewDidUnload方法,当时除了可见的一个。