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

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

作者: 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)

    相关文章

      网友评论

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

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