viewDidLoad中的alloc/init导致IB忽略outlet



我刚刚看到一个非常奇怪的问题,我的视图会忽略来自自定义视图的所有委托调用,因为我在加载时对该项调用了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和我的观点?

因为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报告要容易得多。

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

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)。您可以随心所欲地使用引用,但不能仅通过创建新对象来更改接口实例。

最新更新