I was messing around and just tried implementing a simple non-block / delegate callback function.
Class A.m
@implementation noblocks
-(void)logSomethingAndNotify:(id)object andCallSelector:(SEL)selector {
//some task
NSLog(@"TRYING THIS OUT");
//implement callback functionality
if ([object respondsToSelector:@selector(selector)]) {
[object performSelector:@selector(selector) withObject:object];
}
}
@end
Class B.m
- (void)viewDidLoad {
[super viewDidLoad];
ClassA *noblock = [noblocks new];
[ClassA logSomethingAndNotify:self andCallSelector:@selector(addSubviewAfterDelay)];
}
-(void)addSubviewAfterDelay {
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 100, 100)];
view.backgroundColor = [UIColor blueColor];
[self.view addSubview:view];
});
}
In the implementation file of Class A, if I change this statement:
if ([object respondsToSelector:@selector(selector)]) {
[object performSelector:@selector(selector) withObject:object];
}
to the selector the way it is represented as a method parameter
if ([object respondsToSelector:selector]) {
[object performSelector:selector withObject:object];
}
then I get a memory leak warning from the compiler.
I understand that given the dynamic runtime of Objective-C, sending a selectorless message to an unknown object can potentially be problematic - we don't know the return type of the method and can't be sure that we should retain the object returned (if there is one). What I don't understand is why using performSelector:@selector(selector) vs just using performSelector:selector DOESN'T cause any ARC warning.
This question is NOT a duplicate of others addressing the compiler warning - my question is not about WHY the error is shown so much as why ONE way shows a warning while the OTHER does not.
@selector(SEL)
isn't valid as the whole point of the@selector
keyword is to generate/retrieve theSEL
for the specified selector. Therefore the first case is invalid. The reason for the warning is well documented here and elsewhere. – trojanfoe@selector()
should be a method name. I used the notation@selector(SEL)
to illustrate the fact that you are calling@selector()
on a variable of typeSEL
. – trojanfoe