Too difficult to find out if a method should invoke super

Originator:philip.willoughby
Number:rdar://10483378 Date Originated:23-Nov-2011 01:16 PM
Status:Open Resolved:
Product:iPad SDK Product Version:all
Classification:Serious Bug Reproducible:Always
 
Summary: It is very difficult (possibly impossible) to reliably work out whether a method should call its super-implementation.

Notes:
Class A extends B. B implements protocol C which has optional methods. A implements optional method -d; should it call [super d]?

Obvious answer: maybe. This is not a useful answer. What we want to do is invoke [super d] if and only if something will respond to it.

Apparently sensible answer 1:

    [super d]; // Delete this line if a runtime exception occurs

This does not work because B might implement -d dynamically so this works when you test it and not in the field. Or the implementation of B could change so that the result of this test is no longer correct.

Apparently sensible answer 2:

    if ([super respondsToSelector:_cmd])
        [super d];

This does not work, because NSObject's implementation of -respondsToSelector will find the implementation in A and return YES.

Apparently sensible answer 3:

    if ([[self superclass] instancesRespondToSelector:_cmd])
        [super d];

This works if and only if the superclass knows it always implements -d; if instances dynamically determine whether this method is present this technique will not work.

Apparently sensible 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;
    }

Performance of this is poor if the method in the superclass does not exist because computing templateReason and then comparing it to the exception reason is expensive.

This mechanism is fragile because the format of the exception reason string in this case could be altered in a future SDK or runtime release.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!