viewDidLoad中的alloc / init导致IB忽略出口

时间:2012-07-22 23:48:41

标签: ios memory-management interface-builder uitextfield

我刚刚目睹了一个非常奇怪的问题,我的视图会忽略来自自定义视图的所有委托调用,因为我在加载项上调用了alloc / init。我很好奇为什么。

@synthesize customTextField;

-(void)viewDidLoad {
   // by calling this alloc/init, none of the changes here actually update to the view
   // everything is ignored from here on in.
   // if I comment out the alloc/init line, everything works fine
   self.customTextField = [[UITextField alloc] init];
   self.customTextField.text = @"Some text";
   // setting font and size as well

}

虽然我仍然会调用文本字段委托方法,但没有一个链接到我的特定文本字段。我无法回复customTextField

我确实认识到调用alloc / init会给我一个全新的customTextField实例......但是为什么新实例不能链接到IB和我的视图?

3 个答案:

答案 0 :(得分:2)

因为IB linking != binding

当您在IB中链接变量时,它只是在第一次加载时设置变量一次,就是这样。它没有其他特殊代码来跟踪对它的任何更改,这是有充分理由的。

例如:

您正在设计UITableViewCell,如果您选择了一个单元格,则必须重新排列单元格内的所有内容。在这种情况下,您确定如果您只是重新创建所有子视图并将其重新添加到视图中会更容易,因此您可以执行以下操作:

-(void) layoutSubviews {
    if (cellIsSelected)
    {
        // custom button is an IBOutlet property, which is by default a subview of self
        self.customButton = [UIButton buttonWithType:UIButtonTypeCustom];

        [[self someSubView] addSubview:customButton];
    }
    else {
         // where is customButton located now? is it a subview of self or `someSubView`?
         self.customButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

         // [self addSubview:customButton];
    }
}

因此,IB更容易说let's set this once, and let the programmer figure the rest out而不是IB来尝试跟踪对对象所做的所有更改并将其报告给UI。

答案 1 :(得分:2)

在加载nib后调用

viewDidLoad,此时创建新的UITextField实例将不会与您的nib关联。如果您手动设置新实例,还需要手动设置代理,并将其添加为视图的子视图。

答案 2 :(得分:1)

XIB文件无法知道您正在更改引用。考虑以下代码

NSObject *myObjA = [[NSObject alloc]init]; //create object
NSObject *myObjB = myObjA; //assign reference <- this is the your case after xib load 
myObjB = [[NSObject alloc]init]; //create object, myObjA still lives on.

与加载XIB文件时基本相同;您将获得对实例化对象的引用(在上面的示例中等于myObjB)。您可以使用引用,但不要仅通过创建新对象来更改接口实例。