iPhone SDK:loadView和viewDidLoad有什么区别?

当在iPhone应用程序中处理视图和视图控制器时,任何人都可以解释loadView和viewDidLoad之间的区别吗?

我的个人情况是,我从代码中构build了所有的视图,如果这有所作为,我不会也不会使用Interface Builder。

我发现通常当我将init代码添加到loadView时,我最终得到了一个无限的堆栈跟踪,所以我通常在viewDidLoad中完成所有的子视图构build…但是当我每次执行时都不清楚,什么是放置init代码的更合适的地方。 什么是完美的,是初始化调用的简单图。

谢谢!

我可以猜到这里可能是什么问题,因为我已经做到了:

我发现通常当我将init代码添加到loadView时,我最终得到了无限的堆栈跟踪

不要在-loadView中读取self.view。 只有设置它,不要明白

如果当前没有加载视图,self.view属性访问器将调用 -loadView。 有你的无限recursion。

正如苹果的Interface-Builder之前的例子所展示的,在-loadView中以编程方式构build视图的常用方式更像这样:

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

我不怪你不使用IB。 我坚持使用Instapaper的这种方法,并且发现自己比处理IB的复杂性,界面怪癖和意外的幕后行为更加舒适。

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

viewDidLoad是视图加载完成后调用的方法。 这在调用loadView之后调用。 这是一个地方,你可以覆盖和插入的代码,进行一次加载视图的进一步初始设置。

 viewDidLoad() 

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

 LoadView() 

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

只需添加一些代码示例来演示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]; } 

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

 - (void) loadView { [super loadview]; // init code here... [self.view addSubView:mySubview1]; //etc.. } 

使用loadView最简单的方法是创build一些基本视图控制器,比如UBiewController的子类MyBaseViewController。 在它的loadView方法中以这种方式创build视图:

 -(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]; } 

当您的控制器被要求创buildself.view时, loadView()被调用。 你可以自己来做

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

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

 [super loadView]; 

我真的推荐第二种方法,因为它鼓励inheritance。 只有当你的视图控制器不直接从UIViewControllerinheritance。