Is there any way to send a BOOL
in selector ?
[self performSelector:@selector(doSomething:) withObject:YES afterDelay:1.5];
Or I should use NSInvocation
? Could somebody write a sample please ?
Is there any way to send a BOOL
in selector ?
[self performSelector:@selector(doSomething:) withObject:YES afterDelay:1.5];
Or I should use NSInvocation
? Could somebody write a sample please ?
you can use NSNumber to wrap bools types:
BOOL myBool = YES;
NSNumber *passedValue = [NSNumber numberWithBool:myBool];
[self performSelector:@selector(doSomething:) withObject:passedValue afterDelay:1.5];
and in the selector, to get the bool value, you use:
BOOL value = [recievedObject boolValue];
performSelector
on your own object instance. –
Ardeb In the case that you cannot alter the target-method signature to accept a NSNumber
in place of a BOOL
you can use NSInvocation
instead of 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];
you can use NSNumber to wrap bools types:
BOOL myBool = YES;
NSNumber *passedValue = [NSNumber numberWithBool:myBool];
[self performSelector:@selector(doSomething:) withObject:passedValue afterDelay:1.5];
and in the selector, to get the bool value, you use:
BOOL value = [recievedObject boolValue];
performSelector
on your own object instance. –
Ardeb The simplest way is as follows:
If you have method
-(void)doSomething:(BOOL)flag
and want to performSelecor with flag=NO use
[object performSelector:@selector(doSomething:) withObject:nil];
In case of flag=YES you can send any object, for example, @YES - number from bool
[object performSelector:@selector(doSomething:) withObject:@YES];
Note: don't use @NO ! Only nil will be interpreted as NO in your method with bool argument.
iOS12
and iOS 8.1
on simulator, the flag
always equal to NO
, no matter parameter is @YES
or nil
. –
Adige doSomething:
method, you need to create a wrapper method, like doSomethingObj:(NSNumber*)flag
, which call doSomething:
to finish its work. –
Ardeb NSInteger
parameter, you will see the argument you get is the pointer value from performSelector:withObject:
, instead of the [number integerValue]
. Objc won't unwrap the NSNumber value for you. –
Ardeb use dispatch_after in main thread like this:
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (_animationDuration+1) * NSEC_PER_SEC);
dispatch_after(delayTime, dispatch_get_main_queue(), ^{
[self completeAnimation:NO];
});
if you want to pass a NO,and only a NO, you can put a zero instead
[self performSelector:@selector(doSomething:) withObject:0 afterDelay:1.5];
But remember, just work for zero, doesn't compile with ARC wich disallow implicit conversion
It may not be the most elegant but I created another routine to call the routine with the bool. This keeps the selector stuff simple and doesn't need access to change the original routine.
[Added by Ash] Here's a sample that turns down the receiver's alpha value when a boolean property is set:
- (void) setVisible:(BOOL)visible
{
_visible = visible;
self.alpha = 0.0;
}
- (void) setVisibleUsingNSNumber:(NSNumber *)visible
{
self.visible = [visible boolValue];
}
You can then trigger this after a delay thus:
[self performSelector:@selector(setVisibleUsingNSNumber:)
withObject:[NSNumber numberWithBool:YES]
afterDelay:0.5];
Note that it is also possible to use Grand Central Dispatch these days, in which case you can use the standard setter method inside a block bypassing all this extra code. However, it is much easier to cancel a performSelector call than it is to detect cancellation within a delayed block execution.
Another way of doing this is to pass nil
for NO
and anything else
for YES
[self performSelector:@selector(doSomething:) withObject:nil];
doSomething for BOOL parameter will have NO value
--
[self performSelector:@selector(doSomething:) withObject:[NSNumber numberWithBool:YES]];
doSomething for BOOL parameter will have YES value
--
[self performSelector:@selector(doSomething:) withObject:[NSNumber numberWithBool:NO]];
doSomething for BOOL parameter will have YES value (even passed is number with NO)
@(YES)
for YES
and nil
for NO
–
Christine You cannot send arguments to a selector like this.
You might want to have a look at following answer:
seen this trick form another post, but pass nil for NO and self for YES.
With objective-C literals this can be expressed less verbose.
[self performSelector:@selector(doSomething:) withObject:@(YES) afterDelay:1.5];
Note the @(YES)
i.s.o. YES
If you are Passing the BOOL parameters in static then you can use the following..
------>To Pass 'NO' :
[self performSelector:@selector(doSomething:) withObject:0 afterDelay:1.5];
Now get the result after TimeInterval:
-(void)doSomething:(BOOL)isDoSomething
{
NSLog(isDoSomething?@"Do Something":@"Don't Do Any Thing");
}
Here You will get ' Don't Do Any Thing ' in Log.
------>To Pass 'YES' :
[self performSelector:@selector(doSomething:) withObject:@"1" afterDelay:1.5];
Now get the result after TimeInterval:
-(void)doSomething:(BOOL)isDoSomething
{
NSLog(isDoSomething?@"Do Something":@"Don't Do Any Thing");
}
Here You will get ' Do Something ' in Log.
Instead of relying on NSInvocation or having to modify the method to use a NSNumber this can be done much more elegantly by creating a view e.g :
@interface CLLocationManager(CompatibleView)
@property (nonatomic) BOOL allowsBackgroundLocationUpdates;
@end
@implementation SampleClass
- (void)sampleFunc:(CLLocationManager *)locationManager {
if ([locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
locationManager.allowsBackgroundLocationUpdates = YES;
}
}
@end
Try wrapping your bool in an NSNumber: [NSNumber numberWithBool:myBool]
And the you can get it back with [myNumber boolValue]
I do it this way:
[_button performSelector:@selector(setUserInteractionEnabled:) withObject:[NSString stringWithFormat:@"YES"] afterDelay:nil];
© 2022 - 2024 — McMap. All rights reserved.