iOS - 阻止地狱慢

时间:2012-10-26 23:33:33

标签: iphone ipad block

我在应用程序界面上有大约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方法基本上是两行:设置变量并设置glow imageView的隐藏属性的开启和关闭。因此,这些是所有按钮的快速方法。

我不明白为什么问题出现在某些按钮上而不是其他按钮上,以及为什么当应用程序基本处于空闲状态时块需要很长时间来处理。

任何线索?感谢。

1 个答案:

答案 0 :(得分:5)

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

在您的情况下,您只有10个对象,这不能证明使用并发选项。此外,为什么只使用简单易读,或者快速枚举的原因,为什么使用块使代码复杂化,因为:

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)];
    }
}];