我问这个问题,因为看起来viewDidLoad在初始化程序的主块之前被调用,而我在初始化程序中初始化的类变量在viewDidLoad中变为nil。作为参考,我正在以编程方式执行整个viewcontroller,并且我已经创建了一个自定义初始化程序,因此我可以接受在viewcontroller中使用的各种参数。我的自定义初始化程序当然调用UIViewControllers指定的初始化程序。
基本上,我很好奇将参数发送到UIViewController的正确设计模式是什么?我已经阅读了有关此问题的其他帖子,并没有真正得到明确的答案。我应该跳过初始化程序并手动设置属性(从类外部)?这看起来很简陋,我真的想发送一些参数,我很好奇别人怎么做这个?
答案 0 :(得分:8)
在初始化完成之前调用viewDidLoad的原因可能是因为您在初始化程序中调用了view方法。例如:
- (id)init
{
if ((self = [super init])) {
_thing = 123;
_other = self.view.frame.size.width / 2;
}
return self;
}
加载视图时会调用 viewDidLoad
。一旦调用view
方法,视图就会加载(或者如果您愿意,还可以访问视图属性)。所以你应该避免引用init中的视图。
要回答你的问题,我更喜欢为我的视图控制器创建一个init方法。
- (id)initWithThing:(MyThing *)thing thang:(MyThang *)thang
{
if ((self = [super init])) {
_thing = [thing retain];
_thang = [thang retain];
// ...
}
return self;
}
您还可以在启动后使用属性设置额外变量。我个人更喜欢仅使用可选属性执行此操作,并在init方法中放置必需的属性。这样我就无法使用无效状态初始化视图控制器。
答案 1 :(得分:1)
基本上,您应该为输入数据定义属性,但添加自定义init函数。
如果你创建一个自定义init-Method你应该没问题 - 请记住initWithNibName:bundle:
是UIViewController
的主要初始值设定项,所以这是你想从自定义init-Method调用的。首次使用viewDidLoad
时,您的init-Method将始终调用customVC.view
(来自您的代码或通过框架):
- (id)initWithDataObject:(MyDataObject*)obj
{
self = [super initWithNibName:nil bundle:nil];
if (self) {
self.dataObj = obj;
}
return self;
}
答案 2 :(得分:1)
我将控制器的状态封装在另一个状态对象中。因此控制器通常具有GUI元素的ivars和对该状态对象的引用。
状态对象由我的委托上的StateManager对象处理。因此,让控制器引用另一个控制器并直接设置变量,所有更改都通过此管理器。一点点工作,但不那么凌乱。
任何类都能够检索任何其他控制器的状态并进行更改。这是某些控制器的目的(例如:从youtube中选择视频发生在专用控制器上)。但通常只有一个类获得一个状态来使用initWithState推送下一个控制器:推送的控制器然后将状态应用于viewDidLoad中的GUI或更改从前一个类传递的状态对象。
StateManager保存所有状态对象的字典。我保持状态对象图光,例如:我存储对图像的引用,但不存储图像本身。该应用程序的真正优势在于Core Data,我只使用所有这些来处理GUI状态。 StateManager侦听应用程序resign事件,并使用NSCoding将状态字典保存到磁盘。状态对象ivars总是为零或有意义的值,没有悬空指针。
我正在开发我的第二款iPhone应用程序,这似乎有效,但我也想知道其他人是如何做到这一点的。欢迎任何意见。