In short, the following code calls an existing selector in the super class, and then gives an NSInvalidException:
- (void)applicationWillResignActive:(UIApplication *)application {
if ([super respondsToSelector:@selector(applicationWillResignActive:)])
{
[super applicationWillResignActive:application];
}
This gives the following log exception:
To elaborate... I have a base application delegate (from our new company library) declared as:
I have a base application delegate class, BaseAppDelegate. It is declared as:
@interface CoAppDelegate : NSObject <UIApplicationDelegate>
It implements:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
DebugLog(@"*** ACTIVE ****");
}
It does not implement @selector(applicationWillResignActive:) - or at least what I mean is that I have not specifically written out code for that method. It can't be found in the .h or .m file.
My app has an app delegate that inherits from CoAppDelegate as:
@interface aAppDelegate : CoAppDelegate <UIApplicationDelegate>
I implement both of the above methods as:
- (void)applicationWillResignActive:(UIApplication *)application {
if ([super respondsToSelector:@selector(applicationWillResignActive:)])
{
[super applicationWillResignActive:application];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if ([super respondsToSelector:@selector(applicationDidBecomeActive:)])
{
[super applicationDidBecomeActive:application];
}
}
When the app launches, I get the debug output "*** ACTIVE ****" - as it should.
When I send my app to the background I get that NSInvalidArgumentException stating that the responder does not exist - and it does not exist, so this is the correct exception to throw.
What I need to know is WHY does respondsToSelector give a YES when I am expecting to see a NO? What is the little subtle thing that I am missing?
Instead of [super class]
you should use [self superclass]
:
[[self superclass] instancesRespondToSelector:@selector(method)]
You should use instancesRespondToSelector:
for the following reason stated in the documentation:
You cannot test whether an object inherits a method from its superclass by sending
respondsToSelector:
to the object using thesuper
keyword.This method will still be testing the object as a whole, not just the superclass’s implementation. Therefore, sending
respondsToSelector:
tosuper
is equivalent to sending it toself
. Instead, you must invoke theNSObject
class methodinstancesRespondToSelector:
directly on the object’s superclass.
Your subclass' code should look like this:
- (void)applicationWillResignActive:(UIApplication *)application {
if ([[self superclass] instancesRespondToSelector:_cmd])
{
[super applicationWillResignActive:application];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if ([[self superclass] instancesRespondToSelector:_cmd])
{
[super applicationDidBecomeActive:application];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With