1

我有以下问题:我希望用户在按下按钮时进行下载。在此下载过程中,我想隐藏其他按钮(这将打开下载的文件,因此我想确保在更新尚未完成时没有人尝试打开文件)。在此过程中是否可以隐藏这些按钮?

所以到目前为止我所尝试和经历的:

  • 我总是在最后更改按钮(当不再需要时,因为更新完成)。

我尝试了以下(伪代码):

-(void)updatingprogress
{
    buttona.hidden=TRUE;
}

-(void)updatingfinished
{
    buttona.hidden=FALSE;
}

updateFiles()
{
[self updatingprogress]
... make downloads...
[self updatingfinished]
}

因此,通过记录我看到,我可以在我想要的那一刻进入我的功能,但是在“更新进度”期间没有完成按钮的更改。任何想法如何解决这个问题?谢谢和最好的问候!

4

2 回答 2

4

一个常见问题是您试图在后台线程上更新 UI 元素。如果您的updateFiles方法发生在不同的线程上,您的按钮可能无法正确隐藏。要将方法分派到主线程,您可以使用NSOperationQueueAPI 或GCDAPI。

NSOperationQueue:

[[NSOperationQueue mainQueue] addBlockOperation:^ {
    buttona.hidden = YES;
}];

GCD:

dispatch_async(dispatch_get_main_queue(), ^ {
    buttona.hidden = YES;
});

这两个 API 都做同样的事情。我通常会尝试使用尽可能高的抽象,所以在这种情况下我会使用该NSOperationQueue方法

于 2012-06-01T01:05:55.037 回答
1

另一种可能性是您正在主线程上完成所有工作,但没有考虑到这样一个事实:通常,UIKit 更改在您下拉到运行循环之前不会生效。

背景逻辑是您不希望部分更改可见,例如,如果您写:

// okay, set to success
label.textColor = [UIColor greenColor];  // was previously red
label.text = @"Success";                 // previously said 'Failure'

您明确不希望“失败”一词以绿色显示,然后将“成功”一词更改为“成功”。您希望这两个更改以原子方式发生。Apple 通过将 UIKit 更新批处理并在您计划的任何方法之外影响它们来实现这一点。

因此,如果您在主线程上有一个函数,它做了一些 UI 更改,做了一些工作,然后撤消了 UI 更改,但在任何时候都没有退出到 runloop,那么这些更改将永远不会被看到。

最快的解决方案是:

- (void)updateFiles
{
    [self updatingProgress];
    [self performSelector:@selector(doFileUpdate) withObject:nil afterDelay:0.0];

    // what does the above achieve? It schedules doFileUpdate on the runloop, to
    // occur as soon as possible, but doesn't branch into it now. So when this
    // method returns UIKit will update your display
}

- (void)doFileUpdate
{
    /* heavy lifting here */
    [self updatingFinished];
}
于 2012-06-01T01:33:57.123 回答