Iphone pushViewController,何时设置UILabel文本,是否需要调用setNeedsDisplay?

Iphone pushViewController,何时设置UILabel文本,是否需要调用setNeedsDisplay?,iphone,uiview,uiviewcontroller,Iphone,Uiview,Uiviewcontroller,我今天遇到了一些奇怪的事情,也许有人知道一些事情。我有一个子类UIViewController及其关联的NIB。我在UIViewController方法中设置了标签,所有这些都可以正常工作 现在从另一个类开始,我再次创建ViewController,因为我想重用它。我这样做: MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; vc.titleLabel

我今天遇到了一些奇怪的事情,也许有人知道一些事情。我有一个子类UIViewController及其关联的NIB。我在UIViewController方法中设置了标签,所有这些都可以正常工作

现在从另一个类开始,我再次创建ViewController,因为我想重用它。我这样做:

MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
vc.titleLabel.text = @"testing";
vc.myTextLabel.text = @"yo";
self.navigationController pushViewController:vc animated:NO];
[vc release];
[vc.view setNeedsDisplay]; // why here???
MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
vc.titleLabel.text = @"testing";
vc.myTextLabel.text = @"yo";
self.navigationController pushViewController:vc animated:NO];
[vc release];
这是行不通的。我不知道为什么这不起作用。我想我应该设置所有标签,然后通过将视图控制器推到堆栈上来显示它

但是,如果我这样做:

MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
vc.titleLabel.text = @"testing";
vc.myTextLabel.text = @"yo";
self.navigationController pushViewController:vc animated:NO];
[vc release];
[vc.view setNeedsDisplay]; // why here???
MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
vc.titleLabel.text = @"testing";
vc.myTextLabel.text = @"yo";
self.navigationController pushViewController:vc animated:NO];
[vc release];

这确实有效。这对我来说没有意义。我认为setNeeds Display是在需要重新绘制视图之后调用的。如果我将setNeedsDisplay移动到块的末尾,它将不起作用。它只在街区的一开始起作用,这对我来说很奇怪。以前有人遇到过这种情况,或者知道为什么会这样吗?谢谢。

原因是视图控制器的视图被延迟加载。这意味着当您第一次访问view属性时,只能从nib或通过-loadView加载控制器的视图。如果在加载视图之前尝试访问标签,则标签将为零,并且发送给标签的任何消息都将为无

因此,要强制加载视图,可以执行以下操作:

/* make sure the view is loaded */
[vc view];
/* Access the label properties */
vc.titleLabel.text = @"testing";
但是,在所有情况下,强制加载视图可能不是一个好主意,尤其是在视图控制器不会立即显示并且您希望节省内存的情况下

在这种情况下,您可以在控制器的init方法中创建标签,使其始终存在,并在-viewDidLoad中手动将其添加到视图控制器的视图中,而不是添加到nib中。这将允许标准的延迟加载行为工作,但是类的用户仍然可以在加载视图之前在标签上设置属性


另一种方法是在视图控制器上公开带有关联IVAR的简单NSString属性,以表示视图中的任何标题或文本。然后在-viewdiload中,可以将标签的文本设置为这些属性的值。视图控制器的用户可以在加载视图之前设置这些属性。

原因是视图控制器的视图是延迟加载的。这意味着当您第一次访问view属性时,只能从nib或通过-loadView加载控制器的视图。如果在加载视图之前尝试访问标签,则标签将为零,并且发送给标签的任何消息都将为无

因此,要强制加载视图,可以执行以下操作:

/* make sure the view is loaded */
[vc view];
/* Access the label properties */
vc.titleLabel.text = @"testing";
但是,在所有情况下,强制加载视图可能不是一个好主意,尤其是在视图控制器不会立即显示并且您希望节省内存的情况下

在这种情况下,您可以在控制器的init方法中创建标签,使其始终存在,并在-viewDidLoad中手动将其添加到视图控制器的视图中,而不是添加到nib中。这将允许标准的延迟加载行为工作,但是类的用户仍然可以在加载视图之前在标签上设置属性


另一种方法是在视图控制器上公开带有关联IVAR的简单NSString属性,以表示视图中的任何标题或文本。然后在-viewdiload中,可以将标签的文本设置为这些属性的值。视图控制器的用户可以在加载视图之前设置这些属性。

第二个代码段甚至不会编译。主要是因为vc在声明为第二个之前被引用,因为self.navigationController前面缺少左括号。您确定没有在alloc+init行之后调用setNeedsDisplay吗?这会起作用,因为它会强制vc的视图加载并初始化IBOutlets。第二个代码段甚至不会编译。主要是因为vc在声明为第二个之前被引用,因为self.navigationController前面缺少左括号。您确定没有在alloc+init行之后调用setNeedsDisplay吗?这会起作用,因为它会强制vc的视图加载并初始化IBOutlets。很好的解释。这很有帮助。谢谢,很好的解释。这很有帮助。谢谢