如果通过performSelectorInBackground控制UI会发生什么?

LE *_*ANG 1 user-interface multithreading objective-c uiview ios

我读了一些UI接口只在MainThread上更新的信息.

我需要异步更新一些UIButtons,所以我使用performSelectorInBackground它,它在模拟器和设备(iPad4)上工作正常.

[self performSelectorInBackground:@selector(toggleToUpperWhenSingleShift) withObject:nil];

- (void)toggleToUpperWhenSingleShift{
    shiftStateIndicator = 1;
    for (UIView *aPad in self.subviews) {
        if ( [aPad isKindOfClass:[UIButton class]] ) {
            UIButton *aButPad = (UIButton *)aPad;
            NSMutableString *currentTitle = [NSMutableString stringWithString:[aButPad titleForState:UIControlStateNormal]];
            NSString *firstChar = [currentTitle substringToIndex:1];
            [currentTitle replaceCharactersInRange:NSMakeRange(0, 1) withString:[firstChar uppercaseString]];
            [aButPad setTitle:currentTitle forState:UIControlStateNormal];
            [aButPad setTitle:currentTitle forState:UIControlStateHighlighted];

            currentTitle = [NSMutableString stringWithString:[aButPad titleForState:UIControlStateSelected]];
            firstChar = [currentTitle substringToIndex:1];
            [currentTitle replaceCharactersInRange:NSMakeRange(0, 1) withString:[firstChar uppercaseString]];
            [aButPad setTitle:currentTitle forState:UIControlStateSelected];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我担心如果我保留我的代码会发生一些不需要的功能.谁能解释一下我的细节performSelectorInBackground

为什么不用它来更新UI以及为什么我的应用程序没问题?无论如何调试问题都会欣赏!

Rob*_*ier 7

performSelectorInBackground:对于几乎任何事情来说几乎都不是你想要的(当然也不是自GCD创建以来).它创建了一个你无法控制的新线程.只要您调度给它的方法,该线程就会运行.

通过"小控制"我的意思是你没有得到一个NSThread对象,所以很容易意外地多次调用这个方法并分叉无限数量的线程.我已经在几个程序中看到过这种情况.

在iOS中,您几乎不应该手动创建线程.GCD并且NSOperation几乎可以处理手动线程可以执行的所有操作,但更好.您通常需要线程池,因此您不会一直旋转并减少线程.GCD为您提供.您想限制自己创建的线程数,这样就不会使处理器瘫痪.GCD为您提供.您希望能够轻松确定后台操作的优先级.GCD也为您提供了这一点.

总而言之,我无法弄清楚为什么你要在后台线程上进行上述操作.几乎所有的工作都是UI更新.您绝不能尝试在后台线程上修改UI.它是未定义的行为,当它出错时,它就会出错.它在少数情况下起作用的事实毫无意义.UIKit不是线程安全的.你应该只调用toggleToUpperWhenSingleShift主线程.我没有看到任何应该阻止你的东西,上下文切换到后台线程的开销在这里真的不值得(即使它是安全的,但事实并非如此).