2012-06-01 97 views
1

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

所以我曾尝试和迄今为止经历:

  • 更改按钮我得到的永远只是在最后(当它不再是必需的,因为那时的更新完成)。

我尝试以下(伪):

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

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

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

因此,与记录我看到的,我在我在我想此刻的功能得到,但按键的变化过程中都没有做“updatingprogress”。任何想法如何解决这个问题? 谢谢,最好的问候!

+0

谢谢您的回答!在主线程上工作的想法解决了我的问题。 – Fringer

回答

1

另一种可能性是您正在主线程中执行所有工作,但未能考虑到这样的事实:在下拉到runloop之前,UIKit更改不会生效。

后台逻辑是您不希望部分更改可见,例如,如果你写道:

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

什么您明确不希望是单词“失败”以显示为绿色,则字更改为“成功”。你想让这两个改变以原子方式发生。 Apple通过将UIKit更新批处理到一起并在任何预定方法之外影响它们来实现此目的。

所以,如果你在主线程上有一些功能来做一些用户界面的改变,做一些工作,然后撤销用户界面的改变,但是没有任何一点退出到运行环境,那么改变将永远不会被看到。

最快的解决办法是:

- (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]; 
} 
4

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

NSOperationQueue:

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

GCD:

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

两种这些API做同样的事情。我通常尝试使用highest abstraction possible,因此在这种情况下,我会使用NSOperationQueue方法

+0

这是个好建议。用于大致相同目的的另一种选择是NSObject方法'-performSelector:onMainThread:waitUntilDone:' –

相关问题