将参数发送到UIViewController的最佳方法是什么?

时间:2011-09-29 07:25:00

标签: iphone ios cocoa-touch design-patterns uiviewcontroller

我问这个问题,因为看起来viewDidLoad在初始化程序的主块之前被调用,而我在初始化程序中初始化的类变量在viewDidLoad中变为nil。作为参考,我正在以编程方式执行整个viewcontroller,并且我已经创建了一个自定义初始化程序,因此我可以接受在viewcontroller中使用的各种参数。我的自定义初始化程序当然调用UIViewControllers指定的初始化程序。

基本上,我很好奇将参数发送到UIViewController的正确设计模式是什么?我已经阅读了有关此问题的其他帖子,并没有真正得到明确的答案。我应该跳过初始化程序并手动设置属性(从类外部)?这看起来很简陋,我真的想发送一些参数,我很好奇别人怎么做这个?

3 个答案:

答案 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应用程序,这似乎有效,但我也想知道其他人是如何做到这一点的。欢迎任何意见。