3

我正在开发一个带有两个选项卡的项目。在我的第一个视图控制器上,我试图调用位于我的第二个视图控制器中的方法。第二个视图控制器上的方法更新这个第二个视图控制器上的 UILabel。问题是第二个视图控制器在启动时没有初始化,因此没有正确调用该方法。我可以使用以下手动初始化第二个视图控制器

     if (secondView==nil) {
        secondView = [[SecondView alloc]init];
    }

然后启动该方法(通过在所述方法上放置断点进行测试并验证它确实触发),但我的 UILabel 没有更新,这让我相信第二个视图控制器是在不同的线程上初始化的。

我的问题是:如何在同一个线程上初始化第二个视图控制器,以便当我单击该选项卡时 UI 会更新?有没有办法在 appDelegate 中做到这一点?

我已验证 IBOutlet 已正确连接到标签,.h 文件已正确导入,并且 SecondViewController 的方法在 .H 文件中说明。

代码如下:

FirstViewController.m

-(void)myMethod
{
     [secondView updateLabel];
}

SecondViewController.m
-(void)updateLabel
{
    myLabel.text = myString;
}
4

2 回答 2

4

“我的问题是:如何在同一个线程上初始化第二个视图控制器..”

你不需要。如果您的控制器位于选项卡栏控制器中,则每个选项卡的根控制器在启动时都会被实例化。如果您需要参考它,请使用 self.tabBarController.viewControllers[1] 之类的东西。这将是第二个选项卡中的控制器。您不想分配初始化一个,这将创建一个不同的 SecondView 实例。

但是,即使您获得了对 secondView 的正确引用,您尝试执行的操作也不起作用,因为 secondView 的视图尚未加载,因此尝试更新标签将不起作用。从您的问题中不清楚为什么您要从第一个控制器执行此操作,因为您没有从中传递任何内容。如果这就是你想要做的,那么只需更新 secondController 的 viewDidAppear 方法中的标签。如果你确实想从第一个视图控制器传递一个字符串,那么你应该在 secondView 中有一个字符串属性,并从第一个控制器设置它的值。然后,让 secondView 在 vi​​ewDidAppear 中将其标签的文本设置为该字符串。

于 2013-03-12T04:18:40.580 回答
0

AppDelegate不应从主线程以外的不同线程执行,除非您正在创建自己的线程、使用操作或尝试从异步回调调用 UI(即异步 url 请求?)。

只是好奇......你能检查一下是否myLabel为 nil 吗?另一个快速检查是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];
}
于 2013-03-12T02:37:24.357 回答