iOS | NSProxy
Objective-C作為一種動態訊息型語言,其機制不同於Java ,C#等編譯型語言.
它將資料型別的確定等工作推遲到了執行時期來執行,並且它呼叫方法的方式實質是像物件傳送訊息,根據selector在物件的本類以及父類中的方法列表進行查詢,如果都找不到就會啟動訊息轉發機制.
回到正題,這個話題我想談下OC的單繼承原則.
OC確實是只能單繼承的語言,但是基於執行時的機制,卻有一種方法讓它來實現一下"偽多繼承".就是利用NSProxy這個類.
NSProxy是和NSObject同級的一個類,可以說它是一個虛擬類,它只是實現了<NSObject>的協議.它的作用有點類似於一個複製類,有人曾經笑談它是卡卡西的複製忍術,想想其實也挺貼切的,其實原理確實如此.
過程:
用一個繼承於NSProxy的子類,在它內部實現一些方法,暴露一個公開方法transform,這個方法是使它變身的關鍵.然後它變身之後可以對那些物件傳送訊息,並且可以在內部攔截訊息的內容並修改.
可以說,幾乎可以變身成為任何物件.
直接上個程式碼來展示下
JanProxy.h
#import <Foundation/Foundation.h>
@interface JanProxy : NSProxy
- (void)transformObjc:(NSObject *)objc;
@end
JanProxy.m
#import "JanProxy.h"
@interface JanProxy ()
@property(nonatomic,strong)NSObject *objc;
@end
@implementation JanProxy
- (void)transformObjc:(NSObject *)objc
{
//複製物件
self.objc = objc;
}
//2.有了方法簽名之後就會呼叫方法實現
- (void)forwardInvocation:(NSInvocation *)invocation
{
if (self.objc) {
//攔截方法的執行者為複製的物件
[invocation setTarget:self.objc];
if ([self.objc isKindOfClass:[NSClassFromString(@"Teacher") class]]) {
//攔截引數 Argument:表示的是方法的引數 index:表示的是方法引數的下標
NSString *str = @"攔截訊息";
[invocation setArgument:&str atIndex:2];
}
//開始呼叫方法
[invocation invoke];
}
}
//1.查詢該方法的方法簽名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
NSMethodSignature *signature = nil;
if ([self.objc methodSignatureForSelector:sel]) {
signature = [self.objc methodSignatureForSelector:sel];
}
else
{
signature = [super methodSignatureForSelector:sel];
}
return signature;
}
@end
使用方法
Dog *dog = [[Dog alloc]init];
//OC中方法的呼叫本質上是給這個物件傳送一個訊息
Cat *cat = [[Cat alloc] init];
//開始複製攔截方法
JanProxy *proxy = [JanProxy alloc];
//開始變身成貓
[proxy transformObjc:cat];
//開始調貓的方法
[proxy performSelector:@selector(eat:) withObject:@"貓發出訊息"];
//開始變身成狗
[proxy transformObjc:Dog];
//開始呼叫學生的方法
[proxy performSelector:@selector(shut)];
最後的結果
發現沒有,貓發出訊息已經被子類的內部攔截並且做出了修改.
總結
OC中存在這麼一個默默無聞的類NSProxy,填補了"多繼承"這個空白區.
相關文章
- NSProxy的理解和使用
- 使用 NSProxy 實現訊息轉發
- Objective-C中的複製忍者卡卡西---NSProxyObject
- [iOS] ios的runtimeiOS
- iOS12、iOS11、iOS10、iOS9常見適配iOS
- iOS音訊-AVAudioSessioniOS音訊Session
- ios安全加固 ios 加固方案iOS
- iOS逆向工程 iOS工具篇iOS
- IOSiOS
- iOS-音訊-AVAudioSessioniOS音訊Session
- 【iOS開發】iOS 動畫詳解iOS動畫
- ios加固,ios程式碼混淆,ios程式碼混淆工具, iOS原始碼混淆使用說明詳解iOS原始碼
- iOS上架流程iOS上架流程iOS
- [iOS]適配iOS10問題iOS
- 【ios】ios 對於wkwebview白屏問題iOSWebView
- ReactNative TabBarIOS和NavigatorIOSReacttabBariOS
- iOS 11恐怖故事:iOS安全的沉浮iOS
- iOS 本地通知NSNotificationcenter --- iOS 開發iOS
- 知名iOS開發者Matt Gemmell談iOS 7iOS
- iOS runloopiOSOOP
- iOS AVAssetiOS
- iOS 動畫iOS動畫
- iOS UIAlertActionStyleiOSUI
- iOS排序iOS排序
- iOS CoreDataiOS
- mock in iOSMockiOS
- Error for iOSErroriOS
- iOS - NSCacheiOS
- iOS 定位iOS
- iOS DLNAiOS
- IOS面試iOS面試
- iOS 鎖iOS
- games in iOSGAMiOS
- iostatiOS
- Delphi iOSiOS
- AxiosiOS
- iOS簽名、iOS企業簽名、iOS超級簽名工具使用iOS
- FoneDog Toolkit for iOS on Mac(ios資料恢復)iOSMac資料恢復