iOS | NSProxy

Objective-C作為一種動態(tài)消息型語言,其機制不同于Java ,C#等編譯型語言.
它將數(shù)據(jù)類型的確定等工作推遲到了運行時期來執(zhí)行,并且它調(diào)用方法的方式實質(zhì)是像對象發(fā)送消息,根據(jù)selector在對象的本類以及父類中的方法列表進行查找,如果都找不到就會啟動消息轉(zhuǎn)發(fā)機制.

回到正題,這個話題我想談下OC的單繼承原則.
OC確實是只能單繼承的語言,但是基于運行時的機制,卻有一種方法讓它來實現(xiàn)一下"偽多繼承".就是利用NSProxy這個類.

NSProxy是和NSObject同級的一個類,可以說它是一個虛擬類,它只是實現(xiàn)了<NSObject>的協(xié)議.它的作用有點類似于一個復制類,有人曾經(jīng)笑談它是卡卡西的復制忍術,想想其實也挺貼切的,其實原理確實如此.

過程:
用一個繼承于NSProxy的子類,在它內(nèi)部實現(xiàn)一些方法,暴露一個公開方法transform,這個方法是使它變身的關鍵.然后它變身之后可以對那些對象發(fā)送消息,并且可以在內(nèi)部攔截消息的內(nèi)容并修改.

可以說,幾乎可以變身成為任何對象.

直接上個代碼來展示下

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.有了方法簽名之后就會調(diào)用方法實現(xiàn)
- (void)forwardInvocation:(NSInvocation *)invocation
{
    if (self.objc) {
        //攔截方法的執(zhí)行者為復制的對象
        [invocation setTarget:self.objc];
           
        if ([self.objc isKindOfClass:[NSClassFromString(@"Cat") class]]) {
            //攔截參數(shù) Argument:表示的是方法的參數(shù)  index:表示的是方法參數(shù)的下標
            NSString *str = @"攔截消息";
            [invocation setArgument:&str atIndex:2];
        }
        
        //開始調(diào)用方法
        [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中方法的調(diào)用本質(zhì)上是給這個對象發(fā)送一個消息
    Cat *cat = [[Cat alloc] init];
 
    //開始復制攔截方法
    JanProxy *proxy = [JanProxy alloc];
    //開始變身成貓
    [proxy transformObjc:cat];
    //開始調(diào)貓的方法
    [proxy performSelector:@selector(eat:) withObject:@"貓發(fā)出消息"];
    
    //開始變身成狗
    [proxy transformObjc:Dog];
    //開始調(diào)用學生的方法
    [proxy performSelector:@selector(shut)];

最后的結果

控制臺輸出結果

發(fā)現(xiàn)沒有,貓發(fā)出消息已經(jīng)被子類的內(nèi)部攔截并且做出了修改.

總結

OC中存在這么一個默默無聞的類NSProxy,填補了"多繼承"這個空白區(qū).

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末事期,一起剝皮案震驚了整個濱河市开呐,隨后出現(xiàn)的幾起案子壳嚎,更是在濱河造成了極大的恐慌框舔,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啊片,死亡現(xiàn)場離奇詭異只锻,居然都是意外死亡,警方通過查閱死者的電腦和手機紫谷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門齐饮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笤昨,你說我怎么就攤上這事沈矿。” “怎么了咬腋?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵羹膳,是天一觀的道長。 經(jīng)常有香客問我根竿,道長陵像,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任寇壳,我火速辦了婚禮醒颖,結果婚禮上,老公的妹妹穿的比我還像新娘壳炎。我一直安慰自己泞歉,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布匿辩。 她就那樣靜靜地躺著腰耙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铲球。 梳的紋絲不亂的頭發(fā)上挺庞,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音稼病,去河邊找鬼选侨。 笑死,一個胖子當著我的面吹牛然走,可吹牛的內(nèi)容都是我干的援制。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼芍瑞,長吁一口氣:“原來是場噩夢啊……” “哼晨仑!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤寻歧,失蹤者是張志新(化名)和其女友劉穎掌栅,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體码泛,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡猾封,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了噪珊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晌缘。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖痢站,靈堂內(nèi)的尸體忽然破棺而出磷箕,到底是詐尸還是另有隱情,我是刑警寧澤阵难,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布岳枷,位于F島的核電站,受9級特大地震影響呜叫,放射性物質(zhì)發(fā)生泄漏空繁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一朱庆、第九天 我趴在偏房一處隱蔽的房頂上張望盛泡。 院中可真熱鬧,春花似錦娱颊、人聲如沸傲诵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拴竹。三九已至,卻和暖如春颅痊,著一層夾襖步出監(jiān)牢的瞬間殖熟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工斑响, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钳榨。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓舰罚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親薛耻。 傳聞我的和親對象是個殘疾皇子营罢,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,679評論 0 9
  • 轉(zhuǎn)自:使用NSProxy和NSObject設計代理類的差異 經(jīng)常發(fā)現(xiàn)在一些需要使用消息轉(zhuǎn)發(fā)而創(chuàng)建代理類時, 不同的...
    iOS_肖晨閱讀 2,624評論 0 54
  • 目錄 Objective-C Runtime到底是什么 Objective-C的元素認知 Runtime詳解 應用...
    Ryan___閱讀 1,933評論 1 3
  • 1.理解NSObject和元類 1.1 在OC中的對象和類是什么 對象是在objc.h中定義的 類是在runtim...
    HWenj閱讀 917評論 0 3
  • NSProxy類在分布式對象架構中是很重要的。由于作用比較特別饲漾,NSProxy在Cocoa程序中出現(xiàn)頻率很低蝙搔。 N...
    iOS_肖晨閱讀 1,263評論 0 51