推广

iOS面试题—runtime相关

iseeyu2年前 (2024-02-21)推广127

  • objc_object(id)
    isa_t,关于isa操作相关,弱引用相关,关联对象相关,内存管理相关
  • objc_class (class) 继承自objc_object
    Class superClass,cache_t cache,class_data_bits_t bits
  • isa指针,共用体isa_t

  • isa指向
    关于对象,其指向类对象。
    关于类对象,其指向元类对象。
    实例–(isa)–>class–(isa)–>MetaClass
  • cache_t
    用于快速查找方法执行函数,是可增量扩展的哈希表结构,是局部性原理的最佳运用
 struct cache_t {
    struct bucket_t *_buckets;//一个散列表,用来方法缓存,bucket_t类型,包含key以及方法实现IMP
    mask_t _mask;//分配用来缓存bucket的总数
    mask_t _occupied;//表明目前实际占用的缓存bucket的个数
}
struct bucket_t {
    private:
    cache_key_t _key;
    IMP _imp;
 }
  • class_data_bits_t:对class_rw_t的封装
struct class_rw_t {
     uint32_t flags;
     uint32_t version;
     const class_ro_t *ro;

     method_array_t methods;
     property_array_t properties;
     protocol_array_t protocols;

     Class firstSubclass;
     Class nextSiblingClass;

     char *demangledName;
}    

Objc的类的属性、方法、以及遵循的协议都放在class_rw_t中,class_rw_t代表了类相关的读写信息,是对class_ro_t的封装,而class_ro_t代表了类的只读信息,存储了 编译器决定了的属性、方法和遵守协议

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
    #ifdef __LP64__
    uint32_t reserved;
    #endif

    const uint8_t * ivarLayout;

    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

    method_list_t *baseMethods() const {
    return baseMethodList;
    }
  };
  • method_t
    函数四要素:名称,返回值,参数,函数体
struct method_t {
  SEL name;           //名称
  const char *types;//返回值和参数
  IMP imp;              //函数体
}

二、 对象,类对象,元类对象

  • 类对象存储实例方法列表等信息。

  • 元类对象存储类方法列表等信息。

    superClass是一层层集成的,到最后NSObject的superClass是nil.而NSObject的isa指向根元类,这个根元类的isa指向它自己,而它的superClass是NSObject,也就是最后形成一个环,

三、消息传递

   void objc_msgSend(void /* id self, SEL op, ... */ )
   void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
   struct objc_super {
       /// Specifies an instance of a class.
       __unsafe_unretained _Nonnull id receiver;
       /// Specifies the particular superclass of the instance to message. 
   #if !defined(__cplusplus)  &&  !__OBJC2__
       /* For compatibility with old objc-runtime.h header */
       __unsafe_unretained _Nonnull Class class;
   #else
       __unsafe_unretained _Nonnull Class super_class;
   #endif
       /* super_class is the first class to search */
   };

消息传递的流程:缓存查找–>当前类查找–>父类逐级查找

  • 调用方法之前,先去查找缓存,看看缓存中是否有对应选择器的方法实现,如果有,就去调用函数,完成消息传递(缓存查找:给定值SEL,目标是查找对应bucket_t中的IMP,哈希查找)
  • 如果缓存中没有,会根据当前实例的isa指针查找当前类对象的方法列表,看看是否有同样名称的方法 ,如果找到,就去调用函数,完成消息传递(当前类中查找:对于已排序好的方法列表,采用二分查找,对于没有排序好的列表,采用一般遍历)
  • 如果当前类对象的方法列表没有,就会逐级父类方法列表中查找,如果找到,就去调用函数,完成消息传递(父类逐级查找:先判断父类是否为nil,为nil则结束,否则就继续进行缓存查找–>当前类查找–>父类逐级查找的流程)
  • 如果一直查到根类依然没有查找到,则进入到消息转发流程中,完成消息传递

四、消息转发

+ (BOOL)resolveInstanceMethod:(SEL)sel;//为对象方法进行决议
+ (BOOL)resolveClassMethod:(SEL)sel;//为类方法进行决议
- (id)forwardingTargetForSelector:(SEL)aSelector;//方法转发目标
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)anInvocation;

那么最后消息未能处理的时候,还会调用到
-(void)doesNotRecognizeSelector:(SEL)aSelector`这个方法,我们也可以在这个方法中做处理,避免掉crash,但是只建议在线上环境的时候做处理,实际开发过程中还要把异常抛出来

  • 方法交换(Method-Swizzling)
     + (void)load
   {
       Method test = class_getInstanceMethod(self, @selector(test));
       Method otherTest = class_getInstanceMethod(self, @selector(otherTest));
       method_exchangeImplementations(test, otherTest);
   }

应用场景:替换系统的方法,比如viewDidLoad,viewWillAppear以及一些响应方法,来进行统计信息

  • 动态添加方法
    class_addMethod(self, sel, testImp, "v@:");
    void testImp (void)
    {
        NSLog(@"testImp");
    }
  • @dynamic 动态方法解析
    动态运行时语言将函数决议推迟到运行时
    编译时语言在编译期进行函数决议

  • [obj foo]和objc_msgSend()函数之间有什么关系?
    objc_msgSend()是[obj foo]的具体实现。在runtime中,objc_msgSend()是一个c函数,[obj foo]会被翻译成这样的形式objc_msgSend(obj, foo)。

  • runtime是如何通过selector找到对应的IMP地址的?
    缓存查找–>当前类查找–>父类逐级查找

  • 能否向编译后的类中增加实例变量?
    不能。 编译后,该类已经完成了实例变量的布局,不能再增加实例变量。但可以向动态添加的类中增加实例变量。

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/56855.html

相关文章

阐述企业因推广优化带来的品牌、人才吸金作用。

阐述企业因推广优化带来的品牌、人才吸金作用。

一家公司优化其网站有多重要?它能为企业带来什么?现在几乎每个人的生活都离不开网络,但仍有一些企业对网站的优化和推广不够重视。这是因为这些企业不了解网站优化和推广对企业的重要性,不知道它能给企业带来什么?以下三点是网站优化和推广可以给公司或企业带来的好处。 1、网站优化和推广可以增强企...

如何用极简化框架思维提高工作效率?

如何用极简化框架思维提高工作效率?

编辑导语:在工作中,我们时常会遇到工作效率低下,工作完不成的问题。究其原因,是我们的工作方法出现了错误。作者分享了如何使用极简框架,提高自己工作效率的方法,我们一起来看下吧。 你是不是也会有这样的问题:每天上班坐在自己的工位上...

万相台投放流程是怎样的

万相台投放流程是怎样的

先要选择自己要投放的计划,再做好计划预算,再设置人群,一般不建议设置1w包以下,接下来,上传好创意图,设置投放就行。产品测算是机遇货品的最大投放效率来计算的。...

分享几个数字化营销成功案例~

分享几个数字化营销成功案例~

数字化有用吗?我们企业要不要进行数字化转型,转一下营销压力呢?……等你问这一切的时候,你就快被out了!其他什么也不说了,你看看这些企业,你就知道了!戴尔是数字营销成功的典范。戴尔的成功秘诀并不是主要取决于我们一个比较简易的销售,取得巨大成功的压根取决于成本低,效率高的营销...

了解三种无效外链,避免增加SEO优化工作。

了解三种无效外链,避免增加SEO优化工作。

至于,网站的重要性不言而喻。搜索引擎为网站外链的构建引入了绿色萝卜算法、石榴算法等。此外,百度官员还指定了几种问题外链,这对网站优化没有影响。为了避免人们在下面做“无用的工作”,小编分享三种无效外链,一起来看看吧。 注:问题链明显的特征是非用户或网站的真实推荐。根据这一原理,很容易判...

京东产品怎么推广(~知识分享)

京东产品怎么推广(~知识分享)

一个好的产品推广,是能让产品爆起来的。就像人一样,需要不断地给自己种草一样。不会推广的店铺不仅得不到好的流量与转化,还会因为推广而让店铺被平台惩罚无法再继续生产商品。就像一个不会使用京东平台的人,想要在电商里生存下去,就必须学会如何运营自己的店铺。那么下面我们就来介绍一下,这款产品怎么进行...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片