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的复杂性,界面怪癖和意外的幕后行为更加舒适。
loadView
是UIViewController
中的方法,它将实际加载视图并将其分配给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。