Phi*_*hby 6 objective-c super respondstoselector
Class Child扩展Parent.父实现协议C,它具有可选方法,包括-(void)d.孩子有执行-d; 应该调用[super d]吗?
换句话说,[super d]当且仅当某些内容会响应时,我会编写什么代码来调用?假设我不控制Parent的实现; 它可能随时改变.
这是我想到的所有方法.我目前正在使用4号.
显然是明智的答案1:
[super d]; // Delete this line if a runtime exception occurs when you try it
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为Parent可能会动态实现-d,因此当您测试它而不是在字段中时,它会起作用.或者Parent的实现可能会更改,以便此测试的结果不再正确.
显然是明智的回答2:
if ([super respondsToSelector:_cmd])
[super d];
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为NSObject的-respondsToSelector实现将在Child中找到实现并在所有情况下返回YES.
显然是明智的答案3:
if ([[self superclass] instancesRespondToSelector:_cmd])
[super d];
Run Code Online (Sandbox Code Playgroud)
当且仅当超类知道它总是实现-d时,这是有效的; 如果实例动态确定是否存在此方法,则此方法将不起作用.优于1,因为它将在运行时获取对Parent实现的静态更改.
显然是明智的回答4:
@try
{
[super d];
}
@catch (NSException *exception)
{
NSString *templateReason = [NSString stringWithFormat:
@"-[%@ %@]: unrecognized selector sent to instance %p"
,NSStringFromClass([self superclass])
,NSStringFromSelector(_cmd)
,self];
if (![exception.reason isEqualToString:templateReason])
@throw exception;
}
Run Code Online (Sandbox Code Playgroud)
如果超类中的方法不存在则性能很差,因为计算templateReason然后将其与异常原因进行比较是很昂贵的.
这种机制很脆弱,因为在这种情况下异常原因字符串的格式可以在将来的SDK或运行时版本中更改.
这些都不是必需的.
如果您是某个类或其他类的子类,则您需要知道是否要替换或补充行为.
换句话说,如果实现存在并且您希望以不同方式完成,则不要调用super.
如果实现不存在,则不要调用super.
如果实现确实存在,但你想补充它,你可以调用super.
附录:
任何时候实施都可以改变,与您的问题无关; 重要的是如果界面发生变化.
如果界面不断变化,那么这个类很可能是一个非常差的候选子类,甚至可以使用.