大家一定都听说过一句话,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
@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
@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
@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
@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