iOS 調(diào)用私有方法的問題

問題:已知ClassA,有一個(gè)私有方法test,通過映射的方式授翻,調(diào)用私有方法test。
我的觀點(diǎn)
寫這個(gè)問題答案之前肋拔,我想說的是锈津,我的邏輯思維中,直覺還是不靈敏凉蜂,好多事情琼梆,都想當(dāng)然了,我覺得思維縝密窿吩,直覺很重要茎杂,這個(gè)是天賦,還有就是習(xí)慣纫雁。
像我這樣直覺不靈敏的煌往,遇見問題,一定要仔細(xì)想想,是否有考慮不周的地方刽脖,這個(gè)要養(yǎng)成這樣的習(xí)慣羞海。
另一種觀點(diǎn)
另外跟大洋洋討論這個(gè)題的時(shí)候,又衍生出來了另一個(gè)問題曲管,我覺得也應(yīng)該記錄下來却邓,好好琢磨琢磨。因?yàn)橛懻撨@個(gè)問題的時(shí)候院水,他也沒有答完整腊徙,他總結(jié)說:“1. 現(xiàn)在回答這類問題,總感覺答不上檬某,2. 感覺iOS會(huì)啥技術(shù)撬腾,也說不出來啥體系,感覺自己的知識(shí)體系樹沒有建立起來恢恼,就是遇見問題解決問題民傻。” 我也有這樣的情況场斑,我覺得我以前的開發(fā)饰潜,就是遇見問題,解決問題和簸,再遇見問題,在解決問題碟刺,得過且過锁保,后來又有了改變,開始注重整體的結(jié)構(gòu)代碼機(jī)構(gòu)半沽,開始喜歡學(xué)習(xí)設(shè)計(jì)模式爽柒,學(xué)習(xí)技巧,因?yàn)檫@些經(jīng)驗(yàn)可以有效的避免一些問題的發(fā)生者填,讓代碼變得更加優(yōu)雅浩村,好維護(hù)好修改,其實(shí)還是遇見問題解決問題占哟。

解決這個(gè)問題
解決這個(gè)問題心墅,要注意的幾個(gè)點(diǎn):ClassA ,私有方法test映射榨乎,調(diào)用私有方法

剛開始的想法是:
ClassA 這個(gè)類的權(quán)限問題怎燥,是否能夠引用,如果是public的蜜暑,可以引用可以直接new對(duì)象铐姚,如果是private或者是protect,引用不了就可以通過NSClassFromString來獲得這個(gè)ClassA的類型來進(jìn)行處理肛捍。
私有方法我想簡單了隐绵,這里我開始并沒有考慮到test是否有參數(shù)和返回值的問題
映射就是通過類名找到類的類型之众,為后續(xù)初始化提供準(zhǔn)備
調(diào)用私有方法,msg_send方法依许,或者performForSelector方法棺禾。

#import "A.h"

@implementation A

- (void)test {
    NSLog(@"可以調(diào)用私有方法");
}

@end

    A * a = [[A alloc] init];
//    [a performSelector:NSSelectorFromString(@"test")];
    [a performSelector:@selector(test)];

image.png

從上面打印結(jié)果可以看出,通過performSelector方法是可以調(diào)用test私有方法的悍手,但是會(huì)有警告帘睦。
帶有參數(shù)甚至是多個(gè)參數(shù)的

#import "A.h"

@implementation A

- (void)test:(NSString *)c1 {
    NSLog(@"可以調(diào)用私有方法%@",c1);
}

@end
  A * a = [[A alloc] init];
  [a performSelector:@selector(test:) withObject:@"加了一個(gè)參數(shù)"];

image.png

這個(gè)思路有個(gè)問題不好解決
test這個(gè)方法,沒參數(shù)坦康,有參數(shù)竣付,有多個(gè)參數(shù),通過performSelector這個(gè)api,沒法做出抽象滞欠,只能通過判斷這幾種情況古胆,去硬處理。

從performSelector的這幾個(gè)api的設(shè)計(jì)來看筛璧,猜測運(yùn)行時(shí)的objc_msgSend方法應(yīng)該會(huì)有對(duì)這幾個(gè)perfomeSelector方法的抽象逸绎。

既然用運(yùn)行時(shí),那么就先用運(yùn)行時(shí)的方法夭谤,檢查是否有參數(shù)的問題棺牧。
這個(gè)地方我在做的時(shí)候,有點(diǎn)卡頓朗儒,卡頓的原因是想通過運(yùn)行時(shí)的方法颊乘,通過方法名找到方法,再監(jiān)測這個(gè)方法里面有沒有參數(shù)醉锄,有參數(shù)參數(shù)的類型是什么樣的乏悄。但是發(fā)現(xiàn)運(yùn)行時(shí)的方法,并沒有提供我這個(gè)思路的api恳不。

這個(gè)地方需要換一個(gè)思路檩小,私有方法是不公開的,test這個(gè)私有方法是怎么得到的烟勋,一種情況是能看到源文件规求,也就是.m文件是可以看到的,所以可以直接確定是否有返回值神妹,是否有參數(shù)颓哮。另一種情況是看不到.m文件,看不到文件的鸵荠,就需要通過運(yùn)行時(shí)方法冕茅,打印這個(gè)類中的所有方法,然后找到想要用的方法,打印的時(shí)候姨伤,也是可以把方法的參數(shù)哨坪,返回值類型打印出來的。
所以說乍楚,test這個(gè)方法是人為選擇出來的当编,也就是說我們要調(diào)用這個(gè)方法的時(shí)候,會(huì)明確知道這個(gè)方法是不是有返回值徒溪,是不是有參數(shù)忿偷,有幾個(gè)參數(shù)等等信息。
假設(shè)有5個(gè)參數(shù)的時(shí)候怎么調(diào)用

#import "A.h"

@implementation A
- (void)test:(NSString *)c1 c2:(NSString *)c2 c3:(NSString *)c3 c4:(NSString *)c4 c5:(NSString *)c5 {
    NSLog(@"私有方法含有多個(gè)參數(shù)%@,%@,%@,%@,%@",c1,c2,c3,c4,c5);
}
@end
//調(diào)用代碼
 Class  A = NSClassFromString(@"A");
    id  a = [[A alloc] init];
    ((void (*)(id,SEL,id,id,id,id,id))objc_msgSend)(a,@selector(test:c2:c3:c4:c5:),@"1",@"2",@"3",@"4",@"5");

輸出結(jié)果


image.png

如果有返回值的怎么調(diào)用

#import "A.h"

@implementation A
- (NSString *)test:(NSString *)c1 c2:(NSString *)c2 c3:(NSString *)c3 c4:(NSString *)c4 c5:(NSString *)c5 {
    return [NSString stringWithFormat:@"私有方法含有多個(gè)參數(shù)%@,%@,%@,%@,%@",c1,c2,c3,c4,c5];
}
@end
//調(diào)用代碼
  Class  A = NSClassFromString(@"A");
  id  a = [[A alloc] init];
  NSString * b =  ((NSString * (*)(id,SEL,id,id,id,id,id))objc_msgSend)(a,@selector(test:c2:c3:c4:c5:),@"1",@"2",@"3",@"4",@"5");
  NSLog(@"%@",b);

輸出結(jié)果


image.png

歸納總結(jié)
已知類名臊泌,調(diào)用私有方法鲤桥,比較好的方法是

  1. 創(chuàng)建類的時(shí)候,用反射機(jī)制渠概,得到類class, 然后實(shí)例化茶凳。
  2. 通過實(shí)例對(duì)象,調(diào)用私有方法的時(shí)候播揪,要考慮私有方法是否有有返回值贮喧,是否有參數(shù),根據(jù)不同的情況進(jìn)行處理猪狈。

既然上面的方式可以成功箱沦,那也也可以直接用函數(shù)指針調(diào)用

#import "A.h"

@implementation A

- (void)test {
    NSLog(@"可以調(diào)用私有方法");
}
@end

//調(diào)用方法
    Class  A = NSClassFromString(@"A");
    id  a = [[A alloc] init];
    IMP imp = [a methodForSelector:@selector(test)];
    void  (* tempFunc)(id target, SEL) = (void *)imp;
    tempFunc(a, @selector(test));

只要能拿到私有方法的指針,就可以想辦法通過指針去調(diào)用雇庙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饱普,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子状共,更是在濱河造成了極大的恐慌,老刑警劉巖谁帕,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峡继,死亡現(xiàn)場離奇詭異,居然都是意外死亡匈挖,警方通過查閱死者的電腦和手機(jī)碾牌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來儡循,“玉大人舶吗,你說我怎么就攤上這事≡裣ィ” “怎么了誓琼?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我腹侣,道長叔收,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任傲隶,我火速辦了婚禮饺律,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘跺株。我一直安慰自己复濒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布乒省。 她就那樣靜靜地躺著巧颈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪作儿。 梳的紋絲不亂的頭發(fā)上洛二,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音攻锰,去河邊找鬼晾嘶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛娶吞,可吹牛的內(nèi)容都是我干的垒迂。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼妒蛇,長吁一口氣:“原來是場噩夢啊……” “哼机断!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起绣夺,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤吏奸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后陶耍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奋蔚,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年烈钞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泊碑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毯欣,死狀恐怖馒过,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情酗钞,我是刑警寧澤腹忽,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布来累,位于F島的核電站,受9級(jí)特大地震影響留凭,放射性物質(zhì)發(fā)生泄漏佃扼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一蔼夜、第九天 我趴在偏房一處隱蔽的房頂上張望兼耀。 院中可真熱鬧,春花似錦求冷、人聲如沸瘤运。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拯坟。三九已至,卻和暖如春韭山,著一層夾襖步出監(jiān)牢的瞬間郁季,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工钱磅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梦裂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓盖淡,卻偏偏與公主長得像年柠,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子褪迟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • __block和__weak修飾符的區(qū)別其實(shí)是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用冗恨,...
    LZM輪回閱讀 3,284評(píng)論 0 6
  • 最全的iOS面試題及答案 iOS面試小貼士 ———————————————回答好下面的足夠了-----------...
    zweic閱讀 2,689評(píng)論 0 73
  • ECMAScript關(guān)鍵字 delete do else finally function in instance...
    doudou2閱讀 711評(píng)論 0 0
  • 一、Python簡介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡介】: Python 是一個(gè)...
    _小老虎_閱讀 5,723評(píng)論 0 10
  • 詳情見http://www.runoob.com/python3/python3-built-in-functio...
    ACphart閱讀 213評(píng)論 0 1