举例1
@interface B : NSObject
@property (nonatomic, copy) NSString *name;
+(void)testB;
@end
@implementation B
-(void)testB{
NSLog(@"我是ClassB");
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
[B testB];
}
会crash?
会crash[B testB]: unrecognized selector sent to class 0x106e00520
举例2
@interface NSObject (C)
+(void)testB;
@end
@implementation NSObject (C)
-(void)testB{
NSLog(@"我是nsobject");
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
[NSObject testB];
}
会crash吗?
输出结果我是nsobject
举例3
@interface NSObject (C)
@end
@implementation NSObject (C)
-(void)testB{
NSLog(@"我是nsobject");
}
@end
@interface B : NSObject
@property (nonatomic, copy) NSString *name;
+(void)testB;
@end
@implementation B
-(void)testB{
NSLog(@"我是ClassB");
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
[B testB];
}
会crash吗?
输出结果我是nsobject
举例4
@interface B : NSObject
@property (nonatomic, copy) NSString *name;
+(void)testA;
@end
@implementation B
-(void)testA{
NSLog(@"我是A的父类B");
}
@end
@interface A : B
+(void)testA;
@end
@implementation A
-(void)testA{
NSLog(@"我是A");
}
- (void)viewDidLoad {
[super viewDidLoad];
[A testA];
}
@end
会crash?
crash +[A testA]: unrecognized selector sent to class
举例5
@interface NSObject (C)
@end
@implementation NSObject (C)
-(void)testA{
NSLog(@"我是nsobject");
}
@end
@interface B : NSObject
@property (nonatomic, copy) NSString *name;
+(void)testA;
@end
@implementation B
-(void)testA{
NSLog(@"我是A的父类B");
}
@end
@interface A : B
+(void)testA;
@end
@implementation A
-(void)testA{
NSLog(@"我是A");
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
[A testA];
}
会crash?
会输出 我是nsobject
结果:
举例1,定义了类方法,实现了实例方法, 调用的时候会crash.
举例2.当前类是NSObject,定义了类方法,实现了实例方法 ,调用的时候不会crash, 会调用同名的实例方法
举例3.当前类继承NSObject,定义了类方法,实现了实例方法,调用时由于Class B没有实现类方法testB,就会去B的isa指针指向的B元类去查找类方法testB的IMP,没有找到,就往superClass 根元类NSObject(meta)去找类方法testB的IMP,没找到就往spuerclass NSObject(class)查找类方法testB的IMP(因为runtime查找方法是根据方法名查找的,在这里类方法和实例方法同名,所以就会调用testB)会输出我是nsobject。
举例4.当前类B继承了类A,类A继承了NSobject,A定义了类方法testA,A实现了实例方法testA,B定义不定义testA对结果没影响,B实现实例方法testA,执行结果会crash.
我们分析下原因:
[A testA] A的isa指向的是A(meta),A(meta)里面查找类方法testA的IMP,没有找到就去A(meta)的superclass,B(meta)查找testA的IMP,也没有找到,一直查到NSObject(class)都没有找到类方法testA的IMP,而且NSObject也没有同名的实例方法testA,所以就crash了。
举例5原理同举例3.
结论:
定义了类方法,只实现了实例方法
1.如果当前类是NSObject 会调用同名的实例方法。
2.如果当前类不是NSObject,他的父类如果实现了类方法,就会执行父类的类方法,如果父类(非NSObject)实现了实例方法,依然不会被调用,只要NSObject没有实现该类方法或者同名的实例方法都会crash.(原因:找不到该方法的IMP)
网友评论