希望更多地了解init
和initWithNibName
之间的实际差异。诸如this之类的答案表明最好通过“initWithNibName
”间接调用“init
”。
答案 0 :(得分:31)
通过init间接调用initWithNibName:
更好。您只想在某个时候致电initWithNibName:
。您可以在外部或内部执行此操作。有些人认为最好在内部完成。我实际上有一个名为“LayoutUtil”的类,我保持与布局相关的辅助方法,以避免一遍又一遍地编写繁琐的布局相关代码。这是我加载UIViewController的代码:
+ (id)loadController:(Class)classType {
NSString *className = NSStringFromClass(classType);
UIViewController *controller = [[classType alloc] initWithNibName:className bundle:nil];
return controller;
}
然后我可以这样做:
MyViewController *c = [LayoutUtil loadController:[MyViewController class]];
如果你愿意,你可以在一个类中添加一个名为ughhhh的方法并在那里调用它,它根本不重要。关键是,在init方法中调用initWithNibName并不是一个更好的做法,你只是想确保在启动UIViewController的时候调用它。
- (id)ughhhh
{
self = [super initWithNibName:@"Myview" bundle:nil];
if (self != nil)
{
}
return self;
}
nib文件肯定需要多次加载。每次在UIViewController上调用initWithNibName时,都必须加载xib。很多人加载不属于UIViewController的UIViews,如下所示:
[[NSBundle mainBundle] loadNibNamed:@"nameOfXIBFile" owner:self options:nil];
每次调用此函数时,您都将加载笔尖。
在某些情况下,可以缓存笔尖。一个例子是UITableView - 但是表视图实现了它自己的缓存。操作系统没有自动进行任何缓存。
init
和initWithNibName:
相关,initWithNibName:
自动调用对象的init。
答案 1 :(得分:11)
通过“init”'间接调用“initWithNibName”不是更好。您应该更好地使用适合您需求的任何一种。说[[UIViewController alloc] init]
就像说[[UIViewController alloc] initWithNibName:nil bundle:nil]
一样,所以如果这些是您要传递的参数,那么您也可以使用[[UIViewController alloc] init]
。
回答你的问题:
如果您愿意,可以不同地定义init
和initWithNibName:bundle:
。您只能定义其中一个。例如,UIImagePickerController
仅定义init
,如果您尝试发送initWithNibName:bundle:
,则无法正常运行。或者您可以定义一些完全不同的init...
方法。例如,UINavigationController
仅定义initWithRootViewController:
。无论你定义什么init方法,最终都必须调用它的一个超类的init方法。
是的,可以多次加载笔尖。如果您创建同一视图控制器子类的多个实例,则可能会多次加载相同的nib。实际上,视图控制器的单个实例可能会多次加载其nib。怎么样?如果视图控制器的视图当前不在屏幕上,并且系统内存不足,系统将要求视图控制器释放其视图。如果视图控制器稍后需要将其视图重新放回屏幕上,它将再次加载笔尖。
问题1和2无关。
答案 2 :(得分:2)
第一个问题的答案
理想情况下,每个initWithNibName
内部调用init
,因此您不需要在正常情况下定义两者,但是如果在一种情况下也从loadView
加载View并且从Nib开始,则可以以及来自不同观点的另一个案例。
第二个问题的答案
每次在Stack Nib中加载View时都会加载
第三个问题的答案
否