IPhoneSDK: loadView 和 viewDidLoad 有什么区别?

在 iPhone 应用程序中使用视图和视图控制器时,有人能解释 loadView 和 viewDidLoad 之间的区别吗?

我的个人背景是,我所有的视图都是由代码构建的,我不会也不会使用 Interface Builder,如果这有什么不同的话。

我发现,通常当我向 loadView 添加 init 代码时,最终得到的是一个无限的堆栈跟踪,所以我通常在 viewDidLoad 中完成所有的子视图构建... ... 但我真的不清楚每个子视图在什么时候执行,以及放入 init 代码的更合适的位置是什么。最完美的是初始化调用的简单图表。

谢谢!

57298 次浏览

loadViewUIViewController中实际加载视图并将其分配给 view属性的方法。如果您想以编程方式设置 view属性,UIViewController的子类也会覆盖这个位置。

viewDidLoad是加载视图后调用的方法。这是在调用 loadView 之后调用的。在这里,您可以重写和插入代码,以便在视图加载后对其进行进一步的初始设置。

只是添加了一些代码示例来演示 NilObject 的内容:

- (void)loadView
{
// create and configure the table view
myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped];
myTableView.delegate = self;
myTableView.dataSource = self;
myTableView.scrollEnabled = NO;
self.view = myTableView;


self.view.autoresizesSubviews = YES;
}


- (void)viewDidLoad
{
self.title = @"Create group";


// Right menu bar button is to Save
UIBarButtonItem *saveButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save)];
self.navigationItem.rightBarButtonItem = saveButtonItem;
[saveButtonItem release];
}

我可以猜到问题出在哪里,因为我已经做到了:

我发现,通常在向 loadView 添加 init 代码时,最终会产生一个无限的堆栈跟踪

不要读 self. view in-loadView. 只读 准备好了 it,不要读 走开 it。

View 属性访问器 电话-loadView (如果当前没有加载视图)。

通常在 loadView 中以编程方式构建视图的方法,如苹果公司的 pre-Interface-Builder 示例所示,更像是这样:

UIView *view = [[UIView alloc] init...];
...
[view addSubview:whatever];
[view addSubview:whatever2];
...
self.view = view;
[view release];

我不怪你不用 IB。我在所有 Instapaper 中都坚持使用这种方法,并且发现自己对它比处理 IB 的复杂性、界面怪癖和意想不到的幕后行为更加满意。

要防止在读取 self. view 时发生无限循环,请在加载视图时调用该类的 super 实现。超级实现将为您分配一个新的 UIView。

- (void) loadView {
[super loadview];


// init code here...


[self.view addSubView:mySubview1]; //etc..


}

使用 loadView 最简单的方法是创建某种类型的基视图控制器,比如作为 UIViewController 子类的 MyBaseViewController。在它的 loadView 方法中,创建视图的方式如下:

-(void) loadView {
if ([self viewFromNib]) {
self.view = [self viewFromNib];
} else {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
}
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.view.backgroundColor = [UIColor whiteColor];
}

当您需要制作一些视图控制器时,您只需使用 MyBaseViewController 的子类,在它的 loadView 控制器中,您只需像这样调用[ super loadView ]

//sucblass loadView
-(void) loadView {
[super loadView];


//rest of code like this..
UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame];
[self.view addSubview:myLabel];
[myLabel release];
}
viewDidLoad()

将在从 NIB 加载视图并希望在启动后执行任何自定义时使用

LoadView()

当你想以编程方式创建你的视图时(不使用 Interface Builder)

当控制器被要求创建它的 self.view时,就会调用 loadView()

self.view = [UIView alloc] init...];

或者您的控制器的父 UIController 类已经有一个方法名 -loadView(),它将 self. view 初始化为空白视图。然后你可以打电话

[super loadView];

我确实推荐第二种方法,因为它鼓励继承。只有在视图控制器不是直接从 UIViewController 继承的情况下。

Apple 在 viewDidLoad 上给出的定义提到,它是在控制器的视图加载到内存中之后调用的。用一个简单的术语来说,它是将要加载的第一个方法。

您可能会想,在什么情况下,这种方法才能得到充分利用?答案是,基本上无论你想让应用程序首先加载什么。例如,您可能需要不同的背景颜色,而不是白色,您可以选择蓝色。