简而言之,下面的代码调用超类中的现有选择器,然后给出一个NSInvalidException:
- (void)applicationWillResignActive:(UIApplication *)application {
if ([super respondsToSelector:@selector(applicationWillResignActive:)])
{
[super applicationWillResignActive:application];
}这就产生了以下日志异常:
详细说明..。我有一个基本应用程序委托(来自我们的新公司库)声明为:
我有一个基本的应用程序委托类BaseAppDelegate。声明如下:
@interface CoAppDelegate : NSObject <UIApplicationDelegate> 它执行:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
DebugLog(@"*** ACTIVE ****");
}它没有实现@selector(applicationWillResignActive:) --或者至少我的意思是,我没有为该方法专门编写代码。在.h或.m文件中找不到它。
我的应用程序有一个应用程序委托,从CoAppDelegate继承如下:
@interface aAppDelegate : CoAppDelegate <UIApplicationDelegate>我将上述两种方法都实现为:
- (void)applicationWillResignActive:(UIApplication *)application {
if ([super respondsToSelector:@selector(applicationWillResignActive:)])
{
[super applicationWillResignActive:application];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if ([super respondsToSelector:@selector(applicationDidBecomeActive:)])
{
[super applicationDidBecomeActive:application];
}
}当应用程序启动时,我得到调试输出“* ACTIVE *”-正如它应该的那样。
当我将我的应用程序发送到后台时,我会得到NSInvalidArgumentException声明响应程序不存在-而且它不存在,所以这是正确的异常抛出。
我需要知道的是,为什么当我期望看到一个“不”的时候,respondsToSelector会给出“是”?我错过了什么微妙的小东西?
发布于 2011-10-03 15:28:58
而不是[super class],您应该使用[self superclass]
[[self superclass] instancesRespondToSelector:@selector(method)]发布于 2011-02-14 14:13:14
您应该使用instancesRespondToSelector:,原因如下在文档中说明
不能通过使用
respondsToSelector:关键字向对象发送super来测试对象是否继承了超类的方法。 该方法仍将测试整个对象,而不仅仅是超类的实现。因此,将respondsToSelector:发送到super等同于将其发送到self。相反,您必须直接在对象的超类上调用NSObject类方法instancesRespondToSelector:。
子类的代码应该如下所示:
- (void)applicationWillResignActive:(UIApplication *)application {
if ([[self superclass] instancesRespondToSelector:_cmd])
{
[super applicationWillResignActive:application];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if ([[self superclass] instancesRespondToSelector:_cmd])
{
[super applicationDidBecomeActive:application];
}
}发布于 2014-07-04 08:38:26
[[self superclass] instancesRespondToSelector:<selector>];在某些特殊情况下可能产生不期望的结果。最好是显式地声明类名,而不是self:
[[<ClassName> superclass] instancesRespondToSelector:<selector>];解释:
举个例子:
@protocol MyProtocol <NSObject>
@optional
- (void)foo;
- (void)bar;
@end
@interface A : NSObject <MyProtocol>
@end
@implementation A
- (void)foo {
//Do sth
}
@end
@interface B : A
@end
@implementation B
- (void)bar {
//B may not know which methods of MyProtocol A implements, so it checks
if ([[self superclass] instancesRespondToSelector:@selector(bar)]) {
[super bar];
}
//Do sth
}
@end
@interface C : B
@end
@implementation C
@end那么,想象一下下面的代码:
C *c = [C new];
[c bar];这个密码..。撞车!为什么?让我们深入研究在C实例'c‘上调用bar方法时发生了什么。自我超阶级回来..。B,因为self是C的实例,所以B实例会回复到bar,所以输入if的主体。但是,超级栏试图从B的角度调用超级实现,所以尝试调用A上的bar,这会导致崩溃!
这就是为什么我建议用精确的B超类取代自我超类-这解决了这个问题。
https://stackoverflow.com/questions/4993069
复制相似问题