美文网首页
3期_iOS-weak内部实现

3期_iOS-weak内部实现

作者: 萧修 | 来源:发表于2023-08-10 01:00 被阅读0次

weak修饰的属性,内部会执行

初始化weak指针,这个方法传递了两个参数值,一个是要指向弱引用对象的对象,一个是需要被弱引用的对象

id
objc_initWeak(id *location, id newObj)
{
    if (!newObj) {
        *location = nil;
        return nil;
    }

    return storeWeak<DontHaveOld, DoHaveNew, DoCrashIfDeallocating>
        (location, (objc_object*)newObj);
}

id
objc_storeWeak(id *location, id newObj)
{
    return storeWeak<DoHaveOld, DoHaveNew, DoCrashIfDeallocating>
        (location, (objc_object *)newObj);
}

大体流程为

被weak修饰的变量,系统会在编译时调用objc_initWeak方法,然后调用storeWeak,再调用weak_register_no_lock,在这个方法中,会根据对象的地址hash算出位置,然后插入弱引用表中

如何被销毁呢?

dealloc方法中,标志有弱引用关系,执行weak_clear_no_lock,这个方法会在弱引用表中找到要销毁的对象,并把当前对象的弱应用都取出来,置为nil

此方法传入弱引用计数表,被清除的弱应用对象

void 
weak_clear_no_lock(weak_table_t *weak_table, id referent_id) 
{
    objc_object *referent = (objc_object *)referent_id;

    weak_entry_t *entry = weak_entry_for_referent(weak_table, referent);
    if (entry == nil) {
        /// XXX shouldn't happen, but does with mismatched CF/objc
        //printf("XXX no entry for clear deallocating %p\n", referent);
        return;
    }

    // zero out references
    weak_referrer_t *referrers;
    size_t count;
    
    if (entry->out_of_line()) {
        referrers = entry->referrers;
        count = TABLE_SIZE(entry);
    } 
    else {
        referrers = entry->inline_referrers;
        count = WEAK_INLINE_COUNT;
    }
    
    for (size_t i = 0; i < count; ++i) {
        objc_object **referrer = referrers[i];
        if (referrer) {
            if (*referrer == referent) {
                *referrer = nil;
            }
            else if (*referrer) {
                _objc_inform("__weak variable at %p holds %p instead of %p. "
                             "This is probably incorrect use of "
                             "objc_storeWeak() and objc_loadWeak(). "
                             "Break on objc_weak_error to debug.\n", 
                             referrer, (void*)*referrer, (void*)referent);
                objc_weak_error();
            }
        }
    }
    
    weak_entry_remove(weak_table, entry);
}

相关文章

  • iOS-weak

    weak实现原理: Runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。 weak表其实是...

  • iOS开发之有用的文章

    1、iOS weak 关键字漫谈 : http://mrpeak.cn/blog/ios-weak/ 2、加载gi...

  • iOS-weak原理

    weak是iOS开发中很常见的知识点,大家都知道weak是一个修饰词,作用是对修饰的对象弱引用,在对象被释放的时候...

  • Button和ImageButton的监听事件

    监听事件实现的方式: 1、匿名内部类的实现2、独立类的实现3、接口方式实现 一、匿名内部类 通过匿名内部类,直接在...

  • NSThread

    实现线程常驻如何实现?在方法内部开启一个RunLoopThread实现原理?内部 使用pthread_create...

  • 点击事件的写法

    点击事件的写法 内部实现onclickListener的接口 匿名内部类实现onclickListener 让当前...

  • SDWebImage的内部实现过程

    SDWebImage内部实现过程 SDWebImage 加载图片的内部实现过程。 1.入口setImageWith...

  • JDK1.8ConcurrentSkipListSet的实现

    我们知道Set的内部是用Map实现的,这里内部也是通过Map实现的。内部是一个ConcurrentSkipList...

  • SDWebImage内部实现过程

    SDWebImage底层实现原理及内部实现过程

  • $.isArray内部实现

    isArray: Array.isArray || function( obj ) {return jQuery....

网友评论

      本文标题:3期_iOS-weak内部实现

      本文链接:https://www.haomeiwen.com/subject/ghlmpdtx.html