目标C:某些数据的异步加载 - >我想更新后续标签

问题描述 投票:1回答:1

我有点困惑。我写了一个类,计算一些东西并进行互联网查询。在此查询之后,将使用结果值更新此类的某些NSString属性。

在我的视图控制器中,我创建了这个类的实例。我想在标签中显示等待文本“正在加载...”,直到数据到达。一旦数据准备就绪,我想替换文本。但是我该怎么做?并且根据是否有一个属性,我还想重绘一个这个视图控制器的视图。此外,我不想阻止我的用户界面。

到目前为止这还没有奏效......

self.firstLabel.text = @"Loading...";
self.secondLabel.text = @"Loading...";

UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[indicator setColor:[UIColor colorWithHexString:@"3375cb"]];
indicator.center = self.view.center;
[self.view addSubview:indicator];
[indicator startAnimating];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self.myInstance fillLabelsWithLiveData];

    dispatch_async(dispatch_get_main_queue(), ^{

        [indicator stopAnimating];
        self.firstLabel.text = myInstance.someText;
        self.secondLabel.text = myInstance.someMoreText;
        if(myInstance.myBool){
            //redraw
        }
    });
});
ios objective-c parallel-processing
1个回答
0
投票

你说你的代码不起作用,但你没有说实际行为是什么,所以我想写一下如何调试代码以查看问题所在。

首先,我会在代码中添加一些日志语句,以便了解它实际上做了什么。

NSLog(@"MyViewController: Starting to load...");
self.firstLabel.text = @"Loading...";
self.secondLabel.text = @"Loading...";

UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[indicator setColor:[UIColor colorWithHexString:@"3375cb"]];
indicator.center = self.view.center;
[self.view addSubview:indicator];
[indicator startAnimating];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"MyViewController: Starting to load on background queue...");
    [self.myInstance fillLabelsWithLiveData];
    NSLog(@"MyViewController: Done loading on background queue...");

    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"MyViewController: Updating main queue UI");
        [indicator stopAnimating];
        self.firstLabel.text = myInstance.someText;
        self.secondLabel.text = myInstance.someMoreText;
        if(myInstance.myBool){
            NSLog(@"MyViewController: Will redraw...");
            //redraw
        } else {
            NSLog(@"MyViewController: Will not redraw (myInstance.myBool is NO)");
        }
    });
});

执行此操作时,您将看到问题的确切位置。 (请注意,在整个互联网的教程中,日志消息通常都是超短的。就像NSLog(@"loading...");。问题是,如果你的应用程序中有很多日志,并且每个类都记录这样,那么日志消息就会变得无用。更糟糕的是,你可能会看到“loading ...”打印在控制台上并假设您的代码被调用,而实际上程序中的其他位置打印“loading ...”。所以我总是在NSLog调用中添加一些上下文。(事实上,我从不使用NSLog,我使用自定义日志记录库,也打印文件名和行号。))

只需对您的代码进行一些评论。

使指标居中

indicator.center = self.view.center; // (1a)

这并不是指针在self.view中的中心

indicator.center = centerOf(self.view.bounds); // (1b)

确实。你必须定义centerOf:

CGPoint centerOf(CGRect rect) {
    CGFloat x = CGRectGetMidX(rect);
    CGFloat y = CGRectGetMidY(rect);
    return CGPointMake(x, y);
}

(1a)如果self.view.frame.origin足够接近(0,0),则效果很好。

检查你的代码是否挂起

如果添加日志并查看控制台,可能会出现一些问题:

  • 根本不显示新的日志行=>在这种情况下,您应该检查为什么不调用您的代码
  • 新的日志行打印到某些点,例如“从后台队列上完成加载”永远不会打印到控制台。 =>在这种情况下,显然是中间的代码挂起。
  • 日志看起来不错,但指示灯没有显示。 2个选项: 一切都很快,你只是看不到指标。 后台队列上的加载需要一些时间,但指示器不可见=>指示器的超级视图是否可见?使用Xcode的“检查视图层次结构”功能来检查发生了什么。你的观点在哪里?添加一些代码,如self.view.backgroundColor = [UIColor orangeColor];,看看它是否有所作为。
  • 日志看起来不错,但标签没有更新。 如果是这样的话,我再也帮不了你了。你没有发布真实的代码。您发布了它的简化版本,并且该错误隐藏在该简化背后。
© www.soinside.com 2019 - 2024. All rights reserved.