大家一定都聽說過一句話,OC中沒有任何的真正的私有方法
下邊說一下最近的偶然的理解
OC中,.h文件的作用就是向外暴露的 屬性 方法 協(xié)議 等等都是對外公開的當然屬性要看限定詞protected栖茉、public、private
.m實現(xiàn)了類內(nèi)部的實現(xiàn)細節(jié)孵延,對外是不公開的吕漂,m文件內(nèi)部聲明的 屬性 方法 協(xié)議都是私有的
看下邊的代碼
//
// 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文件中沒有方法聲明尘应,也可以調(diào)用該方法惶凝。
不過當.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實現(xiàn)了這個方法混滔,會調(diào)用category的方法
控制臺打印 TT22[36478:2715064] TTObjc+MM ppS
2)如果category聲明的方法和category對用的類方法名相同的相同,并且category沒有實現(xiàn)了這個方法,會去類里邊查找這個方法坯屿,會調(diào)用類的方法
控制臺打印 TT22[36535:2720312] ppS
最后說一點題外話油湖,同一個方法在類和category中都有聲明和實現(xiàn),對象調(diào)用的時候回調(diào)用category的方法實現(xiàn)
為什么會這樣领跛,只說一下結(jié)論吧乏德,category不是對類的方法覆蓋,只是category的方法吠昭,在Method查找順序的前邊
這部分涉及到runtime部分喊括,以后會詳解解釋一下這個Method的查找原理
Git地址 https://github.com/json-zhao/BlogCode/tree/master/blog01