当你问它view
时UIViewController
,如果视图还没有被实例化(这是你第一次问它),它需要被创建(°)。
当一个 ViewController 需要实例化它的视图时:
- 如果 XIB 与您的 关联,
UIViewController
则从 XIB 加载视图。这意味着 XIB 文件未归档,并且 XIB 中描述的所有对象都已分配/实例化。因此,XIB 中的每个视图都使用alloc
++ (解压缩 XIB 的解码器)initWithCoder:
实例化。因此,您的每个视图都会收到消息autorelease
NSCoder
initWithCoder:
- 如果没有与您关联的 XIB
UIViewController
,它将调用其loadView
方法以允许您以编程方式创建视图。在这种情况下,您可以在其中编写代码来创建视图,例如[[[UIView alloc] initWithFrame:...] autorelease]
. 因此,您的视图将由代码实例化并接收initWithFrame:
消息,而不是initWithCoder:
方法。
UIViewController
通过取消归档 XIB 文件或通过 中的代码创建和实例化视图之一,loadView
加载视图并UIViewController
接收viewDidLoad
消息。
因此,每个视图首先接收initWithFrame:
(如果由代码创建)或initWithCoder:
(如果从 XIB 创建)消息,然后一旦创建了UIViewController
's 的所有视图层次结构,它本身就会接收消息。总是按这个顺序。view
UIViewController
viewDidLoad
@implementation YourCustonUIView
- (id)initWithCoder:(NSCoder*)decoder
{
// here the view is being allocated from the XIB. "alloc" as been called, "initWithCoder" is in progress
// frame is not set at this line, but as soon as we call the super implementation…
self = [super initWithCoder:decoder];
if (self)
{
// Here all the properties of the view set in the XIB file (thru the inspector) are now applied
// Including the frame of the view (and its backgroundColor and all what you set thru IB)
// so self.frame is initialized with the correct value here
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
// here the view is being allocated from code. "alloc" as been called, "initWithFrame" is in progress
// self.frame is not set at this line, but as soon as we call the super implementation…
self = [super initWithFrame:frame];
if (self)
{
// Here the view is initialized with its frame property
// so self.frame is initialized with the correct value here
// and you can initialize every other property from here
}
return self;
}
@end
@implementation YourCustomUIViewController
-(void)viewDidLoad
{
// At that point, the view of your UIViewController has been loaded/created
// (either via XIB or via the loadView method), so either its initWithCoder (if via XIB)
// or its initWithFrame (if via loadView) has been called
// so in either case, its frame has the right value
}
/*
// In case your YourCustomUIViewController does not have a XIB associated with it
// You have to implement this method to provide a view to your UIViewController by code
-(void)loadView
{
// Create a view by code, and give it a frame
UIView* rootView = [[UIView alloc] initWithFrame:CGRectMake(0,0,..., ...)];
rootView.backgroundColor = [UIColor redColor]; // for example
self.view = rootView;
[rootView release];
// at the end of this method, self.view must be non-nil of course.
}
*/
@end
(°) 另一种可能性是视图已被实例化,但后来被释放,因为您在视图不在屏幕上时收到了内存警告,因此视图使用的内存已被回收。但无论如何,视图尚未加载,必须加载/创建