OC動態調用方法


獲取Class的三種方式:

  1/ Class clazz_1 = NSStringFromClass(@"ClassName");

  2/ Class clazz_2 = [ClassName class];

  3/ Class clazz_3 = [ClassInstance class];

  可以直接使用clazz_x來創建對應的類對象: [[clazz_1 alloc] init];

獲取協議(protocol)名

  Protocol *po = [Protocol NSProtocolFromString:@"protocolName"];

判斷是否實現了某個協議:

  [classInstance conformsToProtocol:protocolName];


獲取SEL對象:

  1/ SEL sel = [SEL NSSelectorFromString:@"methodName"];

  2/ SEL sel = @selector(methodFullName);


判斷某個對象是否可以執行某個方法

  [classInstance respondsToSelector:sel];


動態調用方法的兩種方式

  1/ [obj performsToSelector:sel];

  2/ objc_msgSend(receiver, selector, ...);

    2.1/ 需要返回float, 改用objc_msgSend_fpret(receiver, selector, ...);

    2.2/ 需要返回結構體, 改用objc_msgSend_stret(receiver, selector, ...);

    這個方法需要 #import <objc/message.h>


通過函數指針來調用方法

  OC中IMP的定義:

  #if !OBJC_OLD_DISPATCH_PROTOTYPES
  typedef void (*IMP)(void /* id, SEL, ... */ );
  #else
  typedef id (*IMP)(id, SEL, ...);
  #endif

  解釋:
    1/ IMP是一個指向方法/函數的實現的指針. 因為OC是完全兼容C的, 第一種定義是對C,第二種是對OC的(因為OC有方法, 方法需要對象來調用)

    2/ OBJC_OLD_DISPATCH_PROTOTYPES(分發函數原型). 有啥用呢? 上面說了OC中引入了方法的概念, 而C是沒有的. 方法需要對象調用,而函數不用對象. 所以就需要一個指標來確定IMP指向的是函數還是方法, 這個宏就是來做這件事的. 當將返回的IMP強轉為OC的指向方法的指針, 這個宏保持為1, 當我們將返回的IMP保持默認時, 它為0,意為指向C的函數.

 

  OC中使用IMP調用方法:

	    TestClass *testClass = [[TestClass alloc] init];

	    // testWithChar: 是TestClass的一個方法
	    SEL sel = NSSelectorFromString(@"testWithChar:");

	    int (*imp)(id, SEL, char) ;

	    // 將返回的IMP指針強轉為OC方法的指針類型 
	    // OC的方法指針類型, 一定要有id(調用者), SEL(調用者要調用的方法名, 參數列表)
	    imp = (int (*)(id, SEL, char))[testClass methodForSelector:sel];

	    imp(testClass, sel, 'a');

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM