好的,所以说我有第二个线程正在运行,但它想在主线程上操作一些东西,比如UI
项。
-(void)backgroundThread
{
[myButton performSelectorOnMainThread:@selector(setEnabled:) withObject:(BOOL)YES waitUntilDone:YES];
// right here, how could i pass this BOOL to the function
}
我已尝试使用NSNumber
的{{1}},但numberWithBOOL
不接受。{/ p>
答案 0 :(得分:16)
您不能将performSelectorOnMainThread:withObject:waitUntilDone:
与不是Objective-C对象的参数一起使用,也不能使用NSNumber
,因为没有从对象到原始类型的自动拆箱。
一种解决方案是实现一个类似的方法,它接受一个按钮作为参数并改为调用该方法。
例如,在同一个班级中:
- (void)enableButton:(NSButton *)button {
[button setEnabled:YES];
}
和
-(void)backgroundThread{
[self performSelectorOnMainThread:@selector(enableButton:)
withObject:myButton
waitUntilDone:YES];
}
另一种解决方案是使用替代方法(例如NSButton
)在-setEnabledWithNumber:
上实施类别,然后使用该方法:
@interface NSButton (MyButtonCategory)
- (void)setEnabledWithNumber:(NSNumber *)enabled;
@end
@implementation NSButton (MyButtonCategory)
- (void)setEnabledWithNumber:(NSNumber *)enabled {
[self setEnabled:[enabled boolValue]];
}
@end
和
-(void)backgroundThread{
[myButton performSelectorOnMainThread:@selector(setEnabledWithNumber:)
withObject:[NSNumber numberWithBool:YES]
waitUntilDone:YES];
}
答案 1 :(得分:3)
您可以使用块:
BOOL boolValue = YES;
[self performOnMainThreadWait:YES block:^(id owner) {
[button setEnabled:boolValue];
}];
这使用了我对延迟块的实现:
@implementation NSObject (HHBlockPerform)
- (void)performAfterDelay:(NSTimeInterval)delay block:(HHPerformBlock)block
{
[self performSelector:@selector(runBlock:) withObject:[block copy] afterDelay:delay];
}
- (void)performOnMainThreadWait:(BOOL)wait block:(HHPerformBlock)block
{
[self performSelectorOnMainThread:@selector(runBlock:)
withObject:[block copy]
waitUntilDone:wait
modes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
}
- (void)runBlock:(HHPerformBlock)block
{
block(self);
[block release];
}
@end
答案 2 :(得分:3)
是的,performSelectorOnMainThread:withObject:waitUntilDone:
根本不再适用于原始类型。在过去,只要你只有一个参数并且它是一个可以从/向指针无损转换的整数类型,它就有用了。它不安全,并不漂亮,但确实有效。
然而,Apple最近更改了这些方法的实现以保留+释放它们的参数,当该参数包含BOOL或其他非对象类型时,这显然会爆炸。
虽然我过去曾创建过辅助方法,但现在我最喜欢的技术是使用Higher Order Message,如下所示:
[[myButton onMainThread] setEnabled:YES];
HOM实现中使用的NSInvocation
负责包装和解包所有基本类型,而HOM语法使得输入和清除变得容易。
我称这种技术为Little Message Dispatch。