iOS- (IMP)methodForSelector与+ (IMP)instanceMethodForSelector的区别

释放双眼,带上耳机,听听看~!

导语

今天在编码的时候,无意间看到了- (IMP)methodForSelector函数,让我联想到平时经常用的+ (IMP)instanceMethodForSelector函数。这两个函数从字面意思来看很相近,但是既然同时存在,二者一定存在区别。于是,结合开发文档和代码测试,进行了一些探索。

+ (IMP)instanceMethodForSelector:(SEL)aSelector

功能概述:根据指定的sSelector,遍历类的实例方法列表,返回对应的函数指针。
有两个地方需要注意:
一、这是一个类函数,调用者是一个Class;
二、函数返回结果的类型是实例函数指针,而非类函数指针。

代码测试:

@interface TestObject : NSObject
@end

@implementation TestObject

 - (void)testFun
  {
  }

int main(int argc, const char * argv[])
 {
      IMP p = [TestObject instanceMethodForSelector:@selector(testFun)];
      NSLog(@"%p " , p);
      
      return 0;
 }

输出结果:

 2015-12-21 16:17:02.217 TestProject[2916:166056] 0x100000ad0 

猜想:该函数内部实现过程中创建了一个实例对象,然后遍历实例对象的函数列表,搜索指定的函数名对应的函数指针。

– (IMP)methodForSelector:(SEL)aSelector

功能概述:根据指定的sSelector,返回调用者函数列表中对应的函数指针。
有两个地方需要注意:
一、这是一个实例对象函数,调用者可以是实例对象也可以是类对象(在Object C中,类本身也是对象)
二、函数返回结果的类型可能是实例函数指针,也可能是类函数指针。
代码测试:

int main(int argc, const char * argv[])
 {
      TestObject obj = [TestObject new];
    
      IMP pObj = [obj methodForSelector:@selector(testFun)];
    
      IMP pClass = [TestObject methodForSelector:@selector(testFun)];

      NSLog(@"%p" , pObj);
      NSLog(@"%p" , pClass);
      
      return 0;
 }    

输出结果:

2015-12-21 16:39:12.711 TestProject[3002:179046] 0x100000ad0
2015-12-21 16:39:12.713 TestProject[3002:179046] 0x7fff8878bd40

结论:根据上面的输出结果,可以看出实例对象调用- (IMP)methodForSelector与类调用+ (IMP)instanceMethodForSelector输出结果是一致的,都是实例对象的函数指针;而类对象调用- (IMP)methodForSelector输出结果则是类本身的类函数指针。

综述:这两个函数除了类型上的区别之外,- (IMP)methodForSelector函数的使用范围更广一些,既可以获得实例对象函数指针,又能获去类对象函数指针。此外,+ (IMP)instanceMethodForSelector更像是对- (IMP)methodForSelector的一次封装,用来更便捷地获取实例对象的函数指针。

人已赞赏
iOS文章

iOS 中的各种锁

2019-9-25 17:28:18

iOS文章

iOS-KVO底层原理—利用Runtime自定义KVO

2019-9-25 21:32:40

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索