我正在开发一个包含两个标签的项目。在我的第一个视图控制器上,我正在尝试调用位于第二个视图控制器中的方法。第二视图控制器上的方法更新此第二视图控制器上的UILabel。问题是第二视图控制器在启动时没有初始化,因此没有正确调用该方法。我可以使用以下方法手动初始化第二视图控制器
if (secondView==nil) {
secondView = [[SecondView alloc]init];
}
然后启动方法(通过在所述方法上放置一个断点进行测试并验证它确实触发),但我的UILabel没有更新,这让我相信第二个视图控制器在另一个线程上初始化
我的问题是:如何在同一个线程上初始化第二个视图控制器,以便在我点击该选项卡时更新UI?有没有办法在appDelegate中执行此操作 ?
我已经验证了IBOutlet正确连接到标签,正确导入了.h文件,并且在.H文件中声明了SecondViewController的方法。
代码如下:
FirstViewController.m
-(void)myMethod
{
[secondView updateLabel];
}
SecondViewController.m
-(void)updateLabel
{
myLabel.text = myString;
}
答案 0 :(得分:4)
“我的问题是:如何在同一个线程上初始化第二个视图控制器......”
你不需要。如果您的控制器位于标签栏控制器中,则每个选项卡的根控制器都会在启动时进行实例化。如果你需要引用它,那么使用self.tabBarController.viewControllers [1]之类的东西。这将是第二个选项卡中的控制器。您不希望分配init,这将创建一个不同的SecondView实例。
即使您获得了对第二个视图的正确引用,但是您尝试执行的操作将无法正常工作,因为secondView的视图尚未加载,因此尝试更新标签将无法正常工作。从你的问题中不清楚你为什么要从你的第一个控制器那里做这个,因为你没有从中传递任何东西。如果这是您想要做的全部,那么只需更新secondController的viewDidAppear方法中的标签即可。如果你想从第一个视图控制器传递一个字符串,那么你应该在secondView中有一个字符串属性,并从第一个控制器设置它的值。然后,让secondView将其标签的文本设置为viewDidAppear中的该字符串。
答案 1 :(得分:0)
AppDelegate
不应该从主线程以外的其他线程执行,除非您正在创建自己的线程,使用操作或尝试来自异步回调的UI调用(即异步URL请求? )。
好奇......你能检查myLabel
是否为零?另一个快速检查是将myLabel
设置为目标视图控制器的init方法上的值,而不是等待函数调用。
如果你有其他线程并且正在执行对UI的调用,切换到主线程的好方法是使用NSThread
类,如下所示:
- (void) doSomethingOnUI:(NSString*) label{
// if the calling thread is not the main thread
if( ![NSThread isMainThread] )
{
// switch to the main thread
[self performSelectorOnMainThread:@selector(doSomethingOnUI:)
withObject:label
waitUntilDone:YES];
return;
}
[self.myLabel setText: label];
}