The Child class extends the parent. Parent implements the C protocol, which has optional methods, including -(void)d . The child has an implementation -d ; if he calls [super d] ?
In other words, what code do I write to call [super d] if and only if something answers it? Suppose I do not control the implementation of Parent; he can change at any time.
That is all I was thinking. I am currently using number 4.
Obvious reasonable answer 1:
[super d]; // Delete this line if a runtime exception occurs when you try it
This does not work, because Parent can implement -d dynamically, so it works when you check it, and not in the field. Or the implementation of the parent may change, so the result of this test is no longer correct.
Obviously reasonable answer 2:
if ([super respondsToSelector:_cmd]) [super d];
This does not work, because the implementation of NSObject -respondsToSelector will find the implementation in Child and will return YES in all cases.
Obvious reasonable answer 3:
if ([[self superclass] instancesRespondToSelector:_cmd]) [super d];
This works if and only if the superclass knows that it always implements -d; if instances dynamically determine if this method is present, this method will not work. Better than 1, that it will receive static changes in the implementation of Parent at runtime.
Obviously reasonable answer 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; }
The performance of this is bad if the method does not exist in the superclass, because calculating templateReason and then comparing it with the cause of the exception is expensive.
This mechanism is fragile because the string format of the reason for the exception in this case may be changed in a future version of the SDK or runtime.