美文网首页
定义类方法实现了实例方法会怎么样

定义类方法实现了实例方法会怎么样

作者: Lucky_1122 | 来源:发表于2020-06-12 16:04 被阅读0次

举例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)

相关文章

  • 定义类方法实现了实例方法会怎么样

    举例1 会crash?会crash[B testB]: unrecognized selector sent to...

  • Quartz JobRunShell实现

    quartz中,Job接口是要实现execute方法的.JobRunShell run方法会实例化job实现类,然...

  • Java接口中的field

    接口中是不能定义实例变量的,一方面接口不能实例化,实现都是交给实现类去完成的,那么在接口内定义“实例变量”会怎么样...

  • python 实例方法、类方法、静态方法的区别

    实现方式上区别 类,静态方法是装饰器实现 调用上区别 实例方法只能由实例对象调用 定义上区别 类方法实现类逻辑 静...

  • 方法(Method)

    枚举 结构体 类都可以定义实例方法,类型方法 实例方法(Instance Method):通过实例对象调用 类型方...

  • Swift语法 -- [09 - 方法]

    枚举、结构体、类都可以定义实例方法、类型方法 实例方法(Instance Method):通过实例对象调用 类型方...

  • python中元类的__call__方法的作用

    元类是类的类,元类之于类就相当于类之于实例。元类的new方法会创建一个类并返回,就像类的new方法会创建一个实例并...

  • 26.绑定方法

    一、绑定方法与非绑定方 1). 类内部定义的函数,分为两大类: 绑定方法 (对象实例方法、类实例方法) :绑定给谁...

  • From Objective-C to Ruby(4)-类和模块

    类 定义类 OC: ruby: 初始化方法 OC: ruby: 实例变量和属性 OC: ruby: 类方法和对象方...

  • 工厂方法模式

    一、工厂方法模式 定义:定义一个创建对象的接口。但让实现这个接口的类来决定实例化哪个类。 工厂方法让类的实例化推迟...

网友评论

      本文标题:定义类方法实现了实例方法会怎么样

      本文链接:https://www.haomeiwen.com/subject/lzagtktx.html