想在程序运行时判断一个子类是否实现了父类的某个方法,可以比较两个类对应方法的指针是否相等。以 -init 方法为例,如下代码所示:

@interface Test: NSObject
@end

@implementation Test
@end

BOOL check() {
    SEL sel = @selector(init);
    IMP baseInit = [NSObject instanceMethodForSelector:sel];
    IMP testInit = [Test instanceMethodForSelector:sel];
    
    return baseInit == testInit;
}

NSLog(@"%@", check() ? @"true" : @"false");			// true

按照 Objective-C 查找方法的规则,对象会先在自己的方法列表中查找,如果有,则调用;如果没有,则向上去父类里面查找,依此一直到 NSObject

需要注意的是,如果是多层继承体系,即使某个子类没有实现某个方法,也不能确定这个子类和某个父类是同一个实现,如下代码所示:

@interface Base: NSObject
@end

@implementation Base

- (id)init {
    return [super init];
}

@end

@interface Test: Base
@end

@implementation Test
@end

BOOL check() {
    SEL sel = @selector(init);
    IMP baseInit = [NSObject instanceMethodForSelector:sel];
    IMP testInit = [Test instanceMethodForSelector:sel];
    
    return baseInit == testInit;	
}

NSLog(@"%@", check() ? @"true" : @"false");         // false

ParsifalC童鞋之前也分享过相关的内容,提供了几种方法,具体可以参考这里