zoukankan      html  css  js  c++  java
  • 第十一条理解objc_masgSend的作用

    Objetive-C最基本的的东西就是它的消息机制。Objective-C运行时的最基本的东西就是 objc_msgSend, 它就是负责发送一个消息给对象的C函数。

     
    当你写下面这样的代码时:  [tableView cellForRowAtIndexPath:indexPath];
     
    编译器实际上把它转换成下面这样的C函数调用  objc_msgSend(tableView, @selector(cellForRowAtIndexPath:), indexPath);
     

    objc_msgSend的返回类型是id. 如果你需要 让一个方法调用, 返回一个原始的对象(或者C结构体)而不是 对象指针, 那应该怎么办呢?

    执行下面人为捏造的代码(因为一般不会直接调用msgSend),会返回一个编译器错误,因为类型不匹配

    UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
    CGRect rect = objc_msgSend(view, @selector(frame));
    
    
    

    如果你将第2行,改成 [view frame]
    编译器 不会 把它转换成 msgSend, 而是调用 objc_msgSend_stret

    objc_msgSend_stret是一个objc_msgSend的替代版本, 用来返回一个结构体。stret就是 STruct RETurn的缩写。
    另外一个相关的objc_msgSend_fret 返回一个Floating-pointer

     
    函数声明
    void objc_msgSend_stret(void *stretAddr, id theReceiver, SEL theSelector, ....)
     
    几个特殊方法

    objc_msgSend_stret
    如果待发送的消息要返回结构体,那么可交由此函数处理。只有当CPU的寄存器能够容纳得下消息返回类型时,这个函数才能处理此消息。若是返回值无法容纳于CPU寄存器中(比如说返回的结构体太大了),那么就由另一个函数执行派发。此时,那个函数会通过分配在栈上的某个变量来处理消息所返回的结构体。

    objc_msgSend_fpret
    如果消息返回的是浮点数,那么可交由此函数处理。在某些架构的CPU中调用函数时,需要对“浮点数寄存器”(floating-point register)做特殊处理,也就是说,通常所用的objc_msgSend在这种情况下并不合适。这个函数是为了处理x86等架构CPU中某些令人稍觉惊讶的奇怪状况。

    objc_msgSendSuper
    如果要给超类发消息,例如[super message:parameter],那么就交由此函数处理。也有另外两个与objc_msgSend_stret和objc_msgSend_fpret等效的函数,用于处理发给super的相应消息。

     

     1、为了性能,objc_msgSend用汇编写成。存在于objc-msg-x86_64.s中。

      

     2、在上图代码中可以看到,objc_msgSend被分为2个过程:1)在cache中寻找SEL。2)在MethodTable寻找SEL。

     3、CacheLookup中,不断地拿SEL与cache中的缓存比较,比较失败,则跳转到 LCacheMiss标签继续在MethodTable中搜索。

      

      如果想手动查找cache,则需要调用_cache_getimp函数(汇编实现),此函数是个对外接口层,用于保存与准备环境。

      

      _cache_getImp在头文件中objc-private.h中,链接后objc/c代码可以直接调用。

      

     4、MethodTableLookup 是个接口层宏,主要用于保存环境与准备参数,来调用 __class_lookupMethodAndLoadCache3函数(此函数实现于objc-class.mm)。

      

     5、__class_lookupMethodAndLoadCache3函数也是个接口层(C编写),此函数提供相应参数配置,实际功能在lookUpMethod函数中。

      

     6、lookUpMethod函数实现遍历method_list_t,从子类开始,一直遍历到根类。此函数代码较大,不贴图了。文件在objc-class中。
  • 相关阅读:
    数据访问 之 修改数据 (重要)---2017-04-27
    数据访问 之 删除操作 ------ 2017-04-27
    连接数据库的注册、登录----2017-04-26
    数据访问(创建链接、读取数据、例题)--2017-04-25
    C/S 和B/S 详解 --- 2017-04-25
    二阶段测试改错与反思(数据库+面向对象)----2017-04-24
    qq面板(仿版,未完待续中。。。。)---2017-04-24
    网站设计需要注意的20个常犯错误---2017-04-23
    数据库四大特性;
    数据库部分---查询-简单查询;
  • 原文地址:https://www.cnblogs.com/xsyl/p/5817846.html
Copyright © 2011-2022 走看看