ios 呼叫私有方法的幾種方式

2021-08-21 19:19:05 字數 2642 閱讀 5102

// 獲取例項方法

- (void)getmethods

; unsigned int argcount = method_getnumberofarguments(method);

for (int j = 0; j < argcount; j ++)

// 獲取方法返回值型別

char rettype[512] = {};

method_getreturntype(method, rettype, 512);

nslog(@"返回型別值型別= %s", rettype);

}free(methods);

}

呼叫方式:

1. 使用  performselector  下面2和3行結果一樣。這樣比使用物件直接呼叫好處是編譯器不會報錯,也不用方法暴露標頭檔案。

1 person *p = [person new];

2 [p performselector:@selector(eat)]; // log: *** eat====

3 [p performselector:nsselectorfromstring(@"eat")]; // log: *** eat====

2. 使用 objc_msgsend ,對比上面 objc_msgsend 好處是傳遞多個引數時更為方便

person *p = [person new]; // 需要引用 person.h 標頭檔案

objc_msgsend(p, @selector(eat:str2:str3:), @"1", @"2", @"3"); // log: eat====1==2==3

3. 利用函式實現imp,imp型別結構與objc_msgsend底層是同一型別,與2中實現無差別

person *p = [person new];

imp imp = [p methodforselector:@selector(eat)];

void (* tempfunc)(id target, sel) = (void *)imp;

tempfunc(p, @selector(eat)); // log: *** eat====

4. 使用類物件傳送訊息,上面3種方式都需要引用 person.h 標頭檔案,這裡類物件進行呼叫可以解決這個問題

class pclassobj = nsclassfromstring(@"person");

objc_msgsend([pclassobj new], @selector(eat));

5.多引數

-(id)glt_performselector:(sel)selector withobject:(id)object,...ns_requires_nil_termination;

}//nsinvocation是乙個訊息呼叫類,它包含了所有oc訊息的成分:target、selector、引數以及返回值。

nsinvocation *invocation = [nsinvocation invocationwithmethodsignature:signature];

invocation.target = self;

invocation.selector = selector;

nsuinteger argcount = signature.numberofarguments;

// 引數必須從第2個索引開始,因為前兩個已經被target和selector使用

argcount = argcount > 2 ? argcount - 2 : 0;

nsmutablearray *objs = [nsmutablearray arraywithcapacity:0];

if (object)

va_end(args);

}if (objs.count != argcount)

//設定引數列表

for (nsinteger i = 0; i < objs.count; i++)

[invocation setargument:&obj atindex:i+2];

}[invocation invoke];

//獲取返回值

id returnvalue = nil;

if (signature.methodreturnlength != 0 && signature.methodreturnlength)

return returnvalue;}注:

testclass *cls = [[testclass alloc] init];

objc_msgsend(cls, @selector(fun)); //錯誤寫法(arm64崩潰偶爾發生)

((void (*)(id, sel))objc_msgsend)(cls, @selector(fun)); //正確寫法

//eg:

void (*glt_msgsend)(id, sel, nsstring *, nsstring *) = (void (*)(id, sel, nsstring *, nsstring *))objc_msgsend;

glt_msgsend(cls, @selector(eat:say:), @"123", @"456");

獲取ios私有方法

objecitve c的重要特性是runtime 執行時 在interacting with the runtime 互動執行 中,執行時函式部分,蘋果給出了 usr lib libobjc.a.dylib庫,這個共享庫提供支援動態屬性的objective c語言,通過其介面,可以用於開發將其他語言...

反射呼叫類的私有方法與私有內部類的私有方法

package org.example import j ax.lang.model.element.variableelement public class dt class students private string get2 string b private class dt 在stude...

Java呼叫外部私有方法

描述 在寫單元測試的時候,要測試乙個私有方法 解決方案 利用反射,呼叫私有方法 呼叫私有方法 param c class名 param methodname 方法名 param parameters 方法引數 return method實體 throws nosuchmethodexception ...