LE *_*ANG 1 user-interface multithreading objective-c uiview ios
我读了一些UI接口只在MainThread上更新的信息.
我需要异步更新一些UIButton
s,所以我使用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以及为什么我的应用程序没问题?无论如何调试问题都会欣赏!
performSelectorInBackground:
对于几乎任何事情来说几乎都不是你想要的(当然也不是自GCD创建以来).它创建了一个你无法控制的新线程.只要您调度给它的方法,该线程就会运行.
通过"小控制"我的意思是你没有得到一个NSThread
对象,所以很容易意外地多次调用这个方法并分叉无限数量的线程.我已经在几个程序中看到过这种情况.
在iOS中,您几乎不应该手动创建线程.GCD并且NSOperation
几乎可以处理手动线程可以执行的所有操作,但更好.您通常需要线程池,因此您不会一直旋转并减少线程.GCD为您提供.您想限制自己创建的线程数,这样就不会使处理器瘫痪.GCD为您提供.您希望能够轻松确定后台操作的优先级.GCD也为您提供了这一点.
总而言之,我无法弄清楚为什么你要在后台线程上进行上述操作.几乎所有的工作都是UI更新.您绝不能尝试在后台线程上修改UI.它是未定义的行为,当它出错时,它就会出错.它在少数情况下起作用的事实毫无意义.UIKit不是线程安全的.你应该只调用toggleToUpperWhenSingleShift
主线程.我没有看到任何应该阻止你的东西,上下文切换到后台线程的开销在这里真的不值得(即使它是安全的,但事实并非如此).
归档时间: |
|
查看次数: |
955 次 |
最近记录: |