【发布时间】:2011-08-16 08:42:04
【问题描述】:
有什么方法可以在选择器中发送BOOL 吗?
[self performSelector:@selector(doSomething:) withObject:YES afterDelay:1.5];
或者我应该使用NSInvocation?有人可以写一个示例吗?
【问题讨论】:
标签: objective-c iphone selector nsinvocation
有什么方法可以在选择器中发送BOOL 吗?
[self performSelector:@selector(doSomething:) withObject:YES afterDelay:1.5];
或者我应该使用NSInvocation?有人可以写一个示例吗?
【问题讨论】:
标签: objective-c iphone selector nsinvocation
如果您无法更改目标方法签名以接受NSNumber 代替BOOL,您可以使用NSInvocation 代替performSelector:
MyTargetClass* myTargetObject;
BOOL myBoolValue = YES; // or NO
NSMethodSignature* signature = [[myTargetObject class] instanceMethodSignatureForSelector: @selector( myMethodTakingBool: )];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature];
[invocation setTarget: myTargetObject];
[invocation setSelector: @selector( myMethodTakingBool: ) ];
[invocation setArgument: &myBoolValue atIndex: 2];
[invocation invoke];
【讨论】:
您可以使用 NSNumber 来包装 bool 类型:
BOOL myBool = YES;
NSNumber *passedValue = [NSNumber numberWithBool:myBool];
[self performSelector:@selector(doSomething:) withObject:passedValue afterDelay:1.5];
在选择器中,要获取布尔值,请使用:
BOOL value = [recievedObject boolValue];
【讨论】:
performSelector 在您自己的对象实例上。
最简单的方法如下:
如果你有方法
-(void)doSomething:(BOOL)flag
并希望使用 flag=NO use 执行Selecor
[object performSelector:@selector(doSomething:) withObject:nil];
在 flag=YES 的情况下,您可以发送任何对象,例如,@YES - bool 中的数字
[object performSelector:@selector(doSomething:) withObject:@YES];
注意:不要使用 @NO !只有 nil 会在您的带有 bool 参数的方法中被解释为 NO。
【讨论】:
iOS12和iOS 8.1,flag总是等于NO,不管参数是@YES还是nil.
doSomething:方法,你需要创建一个包装方法,比如doSomethingObj:(NSNumber*)flag,它调用doSomething:来完成它的工作。
NSInteger 参数,你会看到你得到的参数是来自performSelector:withObject: 的指针值,而不是[number integerValue]。 Objc 不会为您解开 NSNumber 值。
像这样在主线程中使用 dispatch_after:
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (_animationDuration+1) * NSEC_PER_SEC);
dispatch_after(delayTime, dispatch_get_main_queue(), ^{
[self completeAnimation:NO];
});
【讨论】:
如果你想传递一个 NO,并且只有一个 NO,你可以输入一个 0 来代替
[self performSelector:@selector(doSomething:) withObject:0 afterDelay:1.5];
但请记住,只为零工作,不使用 ARC 编译,不允许隐式转换
【讨论】:
这样做的另一种方法是将 nil 传递给 NO 和 anything else 代表 YES
[self performSelector:@selector(doSomething:) withObject:nil];
doSomething 的 BOOL 参数将没有值
--
[self performSelector:@selector(doSomething:) withObject:[NSNumber numberWithBool:YES]];
对于 BOOL 参数的 doSomething 将具有 YES 值
--
[self performSelector:@selector(doSomething:) withObject:[NSNumber numberWithBool:NO]];
对于 BOOL 参数的 doSomething 将具有 YES 值(即使传递的是 NO 的数字)
【讨论】:
@(YES) 为YES 和nil 为NO
它可能不是最优雅的,但我创建了另一个例程来使用 bool 调用例程。这使选择器的内容保持简单,无需访问即可更改原始例程。
[由 Ash 添加] 这是一个在设置布尔属性时降低接收器 alpha 值的示例:
- (void) setVisible:(BOOL)visible
{
_visible = visible;
self.alpha = 0.0;
}
- (void) setVisibleUsingNSNumber:(NSNumber *)visible
{
self.visible = [visible boolValue];
}
你可以在延迟之后触发它:
[self performSelector:@selector(setVisibleUsingNSNumber:)
withObject:[NSNumber numberWithBool:YES]
afterDelay:0.5];
请注意,现在也可以使用 Grand Central Dispatch,在这种情况下,您可以在块内使用标准 setter 方法,绕过所有这些额外代码。但是,取消 performSelector 调用比在延迟的块执行中检测取消要容易得多。
【讨论】:
【讨论】:
在另一篇文章中看到了这个技巧,但是将 nil 传递给 NO,将 self 传递给 YES。
【讨论】:
使用 Objective-C 文字可以减少冗长的表达。
[self performSelector:@selector(doSomething:) withObject:@(YES) afterDelay:1.5];
注意@(YES) i.s.o。 YES
【讨论】:
如果您在静态中传递 BOOL 参数,那么您可以使用以下..
----->传递“NO”:
[self performSelector:@selector(doSomething:) withObject:0 afterDelay:1.5];
现在得到 TimeInterval 之后的结果:
-(void)doSomething:(BOOL)isDoSomething
{
NSLog(isDoSomething?@"Do Something":@"Don't Do Any Thing");
}
在这里你会得到' Don't Do Any Thing ' 在日志中。
----->传递“是”:
[self performSelector:@selector(doSomething:) withObject:@"1" afterDelay:1.5];
现在得到 TimeInterval 之后的结果:
-(void)doSomething:(BOOL)isDoSomething
{
NSLog(isDoSomething?@"Do Something":@"Don't Do Any Thing");
}
在这里你会得到' Do Something ' 在日志中。
【讨论】:
与其依赖 NSInvocation 或必须修改方法以使用 NSNumber,这可以通过创建视图来更优雅地完成,例如:
@interface CLLocationManager(CompatibleView)
@property (nonatomic) BOOL allowsBackgroundLocationUpdates;
@end
@implementation SampleClass
- (void)sampleFunc:(CLLocationManager *)locationManager {
if ([locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
locationManager.allowsBackgroundLocationUpdates = YES;
}
}
@end
【讨论】:
尝试将您的布尔值包装在 NSNumber 中:[NSNumber numberWithBool:myBool]
你可以用[myNumber boolValue]取回它
【讨论】:
我是这样做的:
[_button performSelector:@selector(setUserInteractionEnabled:) withObject:[NSString stringWithFormat:@"YES"] afterDelay:nil];
【讨论】: