重学OC第八篇:方法查找(下)

本文深入探讨Objective-C的方法查找机制,从lookUpImpOrForward源码解析开始,讲解查找流程,包括在类及父类中查找、方法决议以及转发处理。文章详细阐述了_objc_msgForward_impcache在方法转发过程中的作用,并对方法决议和转发进行了分析。
摘要由CSDN通过智能技术生成

前言

在上一篇中,当缓存中方法找不到后,会调用_lookUpImpOrForward,从注释中可以看到是调用的lookUpImpOrForward方法,可以全局搜索找,也可以跟着断点找到lookUpImpOrForward在objc-runtime-new.mm中的源码。

一、lookUpImpOrForward源码解析

/*
*标准的IMP查找。
*没有LOOKUP_INITIALIZE:尝试避免+初始化(但有时会失败)
*不使用LOOKUP_CACHE:跳过乐观的未锁定查找(但在其他地方使用缓存)
*大多数呼叫者应使用LOOKUP_INITIALIZE和LOOKUP_CACHE
* inst是cls或其子类的实例;如果未知,则为nil。
*如果cls是未初始化的元类,则非nil inst会更快。
*可能会返回_objc_msgForward_impcache。供外部使用的IMP
*必须转换为_objc_msgForward或_objc_msgForward_stret。
*如果您根本不想转发,请使用LOOKUP_NIL。
*/
//behavior = LOOKUP_INITIALIZE | LOOKUP_RESOLVER
IMP lookUpImpOrForward(id inst, SEL sel, Class cls, int behavior)
{
   
    const IMP forward_imp = (IMP)_objc_msgForward_impcache;
    IMP imp = nil;
    Class curClass;

    runtimeLock.assertUnlocked();

    // Optimistic cache lookup 
    if (fastpath(behavior & LOOKUP_CACHE)) {
   
        imp = cache_getImp(cls, sel);
        if (imp) goto done_nolock;
    }
  
	//在isRealized和isInitialized检查期间保持锁,以防止与并发实现竞争。我的理是锁realizeClassMaybeSwiftAndLeaveLocked和initializeAndLeaveLocked的。

    //保证方法查找过程中method-lookup + cache-fill中方法添加的原子性。
    // Otherwise, a category could be added but ignored indefinitely because the cache was re-filled with the old value after the cache flush on behalf of the category.   ???????????不太理解这段,是在查找过程中找到了方法,然后在进入cache-fill前有一个同样的类别方法被动态地添加,导致cache-insert中存入的是旧方法的缓存,而类别的方法永远插入不进去缓存,所以加锁让lookup与cache-fill期间不可以添加类别方法??????????
    runtimeLock.lock();

   	//检查类是不是在二进制文件创建或者通过objc_duplicateClass,objc_initializeClassPair或objc_allocateClassPair创建的,防御CFI攻击
    checkIsKnownClass(cls);

    if (slowpath(!cls->isRealized())) {
   
        cls = realizeClassMaybeSwiftAndLeaveLocked(cls, runtimeLock);
        // runtimeLock may have been dropped but is now locked again
    }

    if (slowpath((behavior & LOOKUP_INITIALIZE) && !cls
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值