ios 呼叫私有方法的幾種方式
// 獲取例項方法 - (void)getMethods { int outCount = 0; Person *p = [Person new]; Method *methods = class_copyMethodList([p class], &outCount); for (int i = 0; i < outCount; i ++) { NSLog(@"=============%d", i); // 獲取方法名 Method method = methods[i]; SEL methodName = method_getName(method); NSLog(@"方法名= %@", NSStringFromSelector(methodName)); // 獲取引數 char argInfo[512] = {}; unsigned int argCount = method_getNumberOfArguments(method); for (int j = 0; j < argCount; j ++) { // 引數型別 method_getArgumentType(method, j, argInfo, 512); NSLog(@"引數型別= %s", argInfo); memset(argInfo, '\0', strlen(argInfo)); } // 獲取方法返回值型別 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: xxx eat====
3 [p performSelector:NSSelectorFromString(@"eat")]; // log: xxx 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: xxx 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;
{
//根據類名以及SEL 獲取方法簽名的例項
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
if (signature == nil) {
NSLog(@"--- 使用例項方法呼叫 為nil ---");
signature = [self methodSignatureForSelector:selector];
if (signature == nil) {
NSLog(@"使用類方法呼叫 也為nil, 此時return");
return nil;
}
}
//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) {
[objs addObject:object];
va_list args;
va_start(args, object);
while ((object = va_arg(args, id))){
[objs addObject:object];
}
va_end(args);
}
if (objs.count != argCount){
NSLog(@"--- objs.count != argCount! please check it! ---");
return nil;
}
//設定引數列表
for (NSInteger i = 0; i < objs.count; i++) {
id obj = objs[i];
if ([obj isKindOfClass:[NSNull class]]) {
continue;
}
[invocation setArgument:&obj atIndex:i+2];
}
[invocation invoke];
//獲取返回值
id returnValue = nil;
if (signature.methodReturnLength != 0 && signature.methodReturnLength) {
[invocation getReturnValue:&signature];
}
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 呼叫私有方法的幾種方式
// 獲取例項方法 - (void)getMethods { int outCount = 0; Person *p = [Person new]; Method *methods = class_copyMethodList([p class], &
iOS 連線外設的幾種方式
聯絡人:石虎 QQ:1224614774 暱稱: 嗡嘛呢叭咪哄 &
關於JAVA呼叫C++的幾種方式和一些問題 UnsatisfiedLinkError
關於JAVA呼叫C++的幾種方式和一些問題 java呼叫c++有幾種方式,1.JNA方式,2,JNative 方式,3.JNI 方式。: 1.JNA方式 public interface MyCLibrary extends Library {
呼叫WebService的幾種方式
一、概覽 方式1: HttpClient:可以用來呼叫webservie服務,也可以抓取網頁資料 版本1:HttpClient3.0.x 版本2:HttpClient4.x.x(目前最新4.5.2) 這2個版本的使用方式不一樣;變動較大
C++ 呼叫com的幾種方式。
1. 使用tlb 檔案: #import "MyCom.tlb" CoInitialize(NULL); MyCom_iPtr ptr(__uuidof(MyCom)); //MyCom為實現類, 它實現了介面MyCom_i; ptr->func();
iOS 執行緒同步幾種方式
多執行緒同步目的有以下幾個方面:第一,對一段程式碼的執行進行保護,如果同時執行一段程式碼,中間的臨時變數可能會互相干擾造成結果不對;第二,對資源的保護,多個執行緒執行不同的程式碼,但是可能涉及同一個資源;第三,訊息傳遞,一個執行緒通知另外一個執行緒發生了一件事。
IOS 之資料庫 的幾種方式
在iOS開發過程中,不管是做什麼應用,都會碰到資料儲存的問題。將資料儲存到本地,能夠讓程式的執行更加 流暢,不會出現讓人厭惡的菊花形狀,使得使用者體驗更好。下面介紹⼀一下資料儲存的方式: 1.NSKeyedArchiver:採用歸檔的形式來儲存資料,該資料物件需要遵守NSCoding協議,並且該物件對應
cxf呼叫服務的幾種方式
客戶端匯入的包 方式一 JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance(); Client client = clientFactory.createClien
iOS 資料儲存的幾種方式
在iOS開發過程中常用的本地化儲存有五種方式: 1.plist (XML屬性列表歸檔 NSArray\NSDictionary) 2.preference (偏好設定\NSUserDefaults) (本質還是通過plist來儲存資料,但是使用更加簡單,無需關注檔案、資料夾
iOS代碼加密的幾種方式
red .sh 最簡 應用安全 adr 變量名 尋找 技術分享 混淆 眾所周知的是大部分iOS代碼一般不會做加密加固,因為iOS APP一般是通過AppStore發布的,而且蘋果的系統難以攻破,所以在iOS裏做代碼加固一般是一件出力不討好的事情。萬事皆有例外,不管iOS、a
iOS關於載入圖片的幾種方式選擇
最近在開發過程中遇到一些效能優化的東西,這次來說說關於圖片載入的效能優化和選擇。 大家都知道建立UIImage常用以下幾種方式 + (nullable UIImage *)imageNamed:(NSString *)name; // load from main bundle
iOS中保證執行緒安全的幾種方式與效能對比
一、前言 前段時間看了幾個開源專案,發現他們保持執行緒同步的方式各不相同,有@synchronized、NSLock、dispatch_semaphore、NSCondition、pthread_mutex、OSSpinLock。後來網上查了一下,發現他們的實現機制各不相同,效能也各不一
Java專案啟動時執行指定方法的幾種方式
很多時候我們都會碰到需要在程式啟動時去執行的方法,比如說去讀取某個配置,預載入快取,定時任務的初始化等。這裡給出幾種解決方案供大家參考。 1. 使用@PostConstruct註解 這個註解呢,可以在Spring載入這個類的時候執行一次。來看一下下方程式碼。
iOS 實現圖片圓角的幾種方式
第一種方法:通過設定layer的屬性 最簡單的一種,但是很影響效能,一般在正常的開發中使用很少. UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 10
a標籤中href呼叫js的幾種方法
我們常用的在a標籤中有點選事件: 1. a href=”javascript:js_method();” 這是我們平臺上常用的方法,但是這種方法在傳遞this等引數的時候很容易出問題,而且javascript:協議作為a的href屬性的時候不僅會導致不必要的觸發window.onbeforeun
js裡宣告函式有幾種方式? var abc = function(x){} 和 function abc(x){} 這兩種宣告方法有什麼不同?
先後者是指函式宣告,前者是指函式表示式,他們之間的區別是後者會在程式碼執行之前被JS直譯器載入到作用域中,這樣一來就可以在程式設計時在定義函式之前呼叫這個函式,此法是有效的;而前者則是在程式碼執行到那一行時候才會有定義,此外函式表示式是建立了一個匿名函式,然後將
spring mvc 實現遠端服務呼叫的幾種方式
org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter 實現遠端服務呼叫 (1)httpinvoker方式 伺服器客戶端都是spring時推薦這種方式 服務端 必須要實現 bean實體類
iOS NSthread & Thread 開啟執行緒的幾種方式
一、開啟執行緒執行指定物件的方法 /** 引數1: 執行引數2方法的物件 引數2: 開啟執行緒後執行的方法 引數3: 傳遞的物件資料(引數2的方法可以直接用) */ // OC - (
java呼叫webservice介面 幾種方法
webservice的 釋出一般都是使用WSDL(web service descriptive language)檔案的樣式來發布的,在WSDL檔案裡面,包含這個webservice暴露在外面可供使用的介面。今天搜尋到了非常好的 webservice provide
Java呼叫Restful API介面幾種方式
2018年01月16日 22:18:40 Exceed Oneself 閱讀數:1968 摘要:最近有一個需求,為客戶提供一些Restful API 介面,QA使用postman進行測試,但是postman的測試介面與java呼叫的相似但並不相同,於是想自己