1

我在应用程序的界面上有大约 10 个对象。这些对象基本上是一个按钮,具有发光显示哪个按钮在给定时间处于活动状态。当一个按钮被选中时,它的发光被打开,而所有其他按钮的发光被关闭。

要打开和关闭发光,我有这个

[buttons enumerateObjectsWithOptions:NSEnumerationConcurrent
                                     usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if (obj == sender)
            [(myButtonClass *)obj showGlow];
    else {
            [(myButtonClass *)obj hideGlow];
    }
}];

但我被迫改成这个

[buttons enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

    if (obj == sender)
            [(myButtonClass *)obj showGlow];
    else {
            [(myButtonClass *)obj hideGlow];
    }
}];

删除枚举的并发部分。问题在于,特别是对于某些按钮,发光需要 5 秒才能打开或关闭,但始终只针对相同的按钮。我的印象是它们处于一种按顺序处理的队列中(?????!!!)

showGlow/hideGlow 方法基本上是两行:设置一个变量和设置发光图像视图的隐藏属性打开和关闭。因此,这些是所有按钮的快速方法。

我不明白为什么某些按钮会出现问题,而其他按钮则不会,以及为什么当应用程序基本上空闲时处理一个块需要这么长时间。

任何线索?谢谢。

4

1 回答 1

5

“缓慢”的 UI 更新的一个原因可能是,当使用该NSEnumerationConcurrent选项时,枚举发生在主线程以外的线程上。由于所有 UI 更新都应该发生在主线程上,因此您的 UI 更改不会立即反映,而是在运行循环刷新所有更改后延迟。

在您的情况下,您只有 10 个对象,这不证明使用并发选项是合理的。此外,当您可以使用易于阅读的或快速枚举时,为什么要使用块使代码复杂化,forin:

for (UIButton *button in buttons) {
    if (button == sender) [button showGlow];
    else [button hideGlow];
}

如果您在某处启动活动指示器,然后在后台线程中停止它,您可以试验并观察相同的延迟 UI 更新。它将需要几秒钟才能真正停止。

如果你坚持使用块,你必须在主线程中调用所有 UIKit 方法:

[buttons enumerateObjectsWithOptions:NSEnumerationConcurrent
                                 usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if (obj == sender)
        // One possibility with GCD and dispatch_async on the main queue
        dispatch_async(dispatch_queue_get_main(), ^{[(myButtonClass *)obj showGlow];});
    else {
        // another possibility to call the selector on the main thread
        [(myButtonClass *)obj performSelectorOnMainThread:@selector(hideGlow)];
    }
}];
于 2012-10-26T23:52:40.747 回答