是否是曾經在別人面前誇下海口:Objective-C
中全部的類的基類都是NSObject
;我以前也一直也這麼覺得的,可是認真看了下官方文檔:java
啪啪,好響,好疼~(看來英文水平也很重要啊......) 不賣關子了,咱們今天要討論的就是NSProxy
。它是跟NSObject
屬於同一級別的類,是個抽象類,只是實現了<NSObject>
的協議;編程
按照官方的定義:NSProxy
是一個爲對象定義接口的抽象父類,而且爲其它對象或者一些不存在的對象扮演了替身角色。一般,給proxy的消息被轉發給實際對象或者致使proxy加載(轉化它爲)實際對象。NSProxy
的子類能被用來實現透明的分佈式消息(例如:NSDistantObject)或者延緩要花費昂貴代價建立的對象的實現。app
下面咱們看看NSProxy
是怎麼複製別的類(幾乎全部類)的:分佈式
咱們先建立一個類繼承自NSProxy
:學習
#import "KakashiProxy.h"
@interface KakashiProxy ()
@property(nonatomic,strong)NSObject *objc;
@end
@implementation KakashiProxy
- (void)changeObj:(NSObject *)obj {
self.objc = obj;
}
//方法簽名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
NSMethodSignature *signature = nil;
if ([self.objc methodSignatureForSelector:sel]) {
signature = [self.objc methodSignatureForSelector:sel];
}else {
signature = [super methodSignatureForSelector:sel];
}
return signature;
}
//調用方法實現
- (void)forwardInvocation:(NSInvocation *)invocation {
if ([self.objc respondsToSelector:invocation.selector]) {
NSString *selName = NSStringFromSelector(invocation.selector);
NSLog(@"selector name : %@",selName);
//這裏咱們能夠作一些邏輯處理,好比埋點統計之類的
[invocation invokeWithTarget:self.objc];
}else {
[super forwardInvocation:invocation];
}
}
@end
複製代碼
能夠看到咱們重寫了兩個方法:methodSignatureForSelector:
和forwardInvocation:(NSInvocation *)invocation
,前者是實現方法簽名的,咱們能夠在這個方法中,直接將咱們複製的對象進行方法簽名,而後生成NSInvocation
。接着方法forwardInvocation
會被調用,在這個方法中,咱們直接將invacation
的target
設置爲咱們複製的對象。在這個方法中咱們能夠作一點事情,好比根據類名作一些邏輯,也能夠作一些數據埋點之類的。 而後咱們看看怎麼使用這個複製忍者的: 咱們隨便定義兩個類,併爲每一個類設置了一個方法:atom
Parker-Dog.h
spa
#import "Parker-Dog.h"
@implementation Parker_Dog
- (void)bite {
NSLog(@"卡卡西召喚通靈獸Paker並咬住了再不斬!");
}
@end
複製代碼
Wood.h
3d
#import "Wood.h"
@implementation Wood
- (void)boom{
NSLog(@"變!木頭!...");
}
複製代碼
調用:code
//初始化一個木頭
Wood *wood = [[Wood alloc] init];
//初始化一個帕克
Parker_Dog *paker = [[Parker_Dog alloc] init];
//初始化一個卡卡西
KakashiProxy *proxy = [KakashiProxy alloc];
//變木頭
[proxy changeObj:wood];
//調用木頭的方法
[proxy performSelector:@selector(boom) withObject:nil];
//變帕克
[proxy changeObj:paker];
//調用帕克的方法
[proxy performSelector:@selector(bite) withObject:nil];
複製代碼
控制檯輸出: orm
這樣,咱們經過proxy
這個類實現了複製wood
和paker
,能夠分別調用各個類的方法了。
其實也不能叫複製吧,你們也能夠看到,這個實現其實就是利用了runtime
的消息轉發機制。這篇文章就算是對NSProxy
的一個簡單認識吧,還有些NSProxy
的高級用法可能筆者尚未學習到,還要繼續努力,有時間須要深刻研究下這個特殊的類。
參看文章