美文网首页
你真的了解OC中没有真正的私有方法的这句话么

你真的了解OC中没有真正的私有方法的这句话么

作者: json_jie | 来源:发表于2018-02-25 20:17 被阅读36次

    大家一定都听说过一句话,OC中没有任何的真正的私有方法

    下边说一下最近的偶然的理解

    OC中,.h文件的作用就是向外暴露的 属性 方法 协议 等等都是对外公开的当然属性要看限定词protected、public、private

    .m实现了类内部的实现细节,对外是不公开的,m文件内部声明的 属性 方法 协议都是私有的


    看下边的代码

    //
    //  ViewController.h
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    
    @end
    
    
    
    //
    //  ViewController.m
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        Class obj = NSClassFromString(@"TTObjc");
        NSObject *ob = [[obj alloc] init];
        SEL methodSel = NSSelectorFromString(@"ppS");
        [ob performSelectorOnMainThread:methodSel withObject:nil waitUntilDone:YES];
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
    
    
    
    
    
    
    
    
    //
    //  TTObjc.h
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface TTObjc : NSObject
    //-(void)ppS;
    @end
    
    //
    //  TTObjc.m
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import "TTObjc.h"
    
    @implementation TTObjc
    -(void)ppS{
        NSLog(@"ppS");
    }
    @end
    
    

    注意 TTObjc.h 文件 无论 -(void)ppS;方法是不是被注释掉
    控制台输出都是 ** TT22[36247:2692455] ppS**

    这也就解释了 OC中没有任何的真正的私有方法

    我们只要知道对象的方法名称,即使对象类的.h文件中没有方法声明,也可以调用该方法。

    不过当.h 文件没有声明, 通过 [obj method]这么做编译器会报错。

    2、通过category做个方法声明也不会引起编译器报错


    
    //
    //  ViewController.h
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    
    @end
    
    
    
    //
    //  ViewController.m
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "TTObjc.h"
    #import "TTObjc+MM.h"
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        TTObjc *tt = [[TTObjc alloc] init];
        [tt ppS];
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
    
    
    
    
    
    //
    //  TTObjc.h
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface TTObjc : NSObject
    //-(void)ppS;
    @end
    
    //
    //  TTObjc.m
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import "TTObjc.h"
    
    @implementation TTObjc
    -(void)ppS{
        NSLog(@"ppS");
    }
    @end
    
    
    
    
    //
    //  TTObjc+MM.h
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import "TTObjc.h"
    
    @interface TTObjc (MM)
    -(void)ppS;
    @end
    
    
    //
    //  TTObjc+MM.m
    //  TT22
    //
    //  Created by jie on 2018/2/25.
    //  Copyright © 2018年 jie. All rights reserved.
    //
    
    #import "TTObjc+MM.h"
    
    @implementation TTObjc (MM)
    //-(void)ppS{
    //    NSLog(@"TTObjc+MM    ppS");
    //}
    @end
    
    
    

    通过category这个方式不仅证明了 OC中没有真正的私有方法的

    类的.h 没有声明方法的前提。
    1)如果category声明的方法和category对用的类方法名相同的相同,并且category实现了这个方法,会调用category的方法
    控制台打印 TT22[36478:2715064] TTObjc+MM ppS
    2)如果category声明的方法和category对用的类方法名相同的相同,并且category没有实现了这个方法,会去类里边查找这个方法,会调用类的方法
    控制台打印 TT22[36535:2720312] ppS


    最后说一点题外话,同一个方法在类和category中都有声明和实现,对象调用的时候回调用category的方法实现

    为什么会这样,只说一下结论吧,category不是对类的方法覆盖,只是category的方法,在Method查找顺序的前边
    这部分涉及到runtime部分,以后会详解解释一下这个Method的查找原理

    Git地址 https://github.com/json-zhao/BlogCode/tree/master/blog01

    相关文章

      网友评论

          本文标题:你真的了解OC中没有真正的私有方法的这句话么

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