[iOS知识简记]-Runtime-源码分析

runtime.h

枚举时修改检测原理:

/** 
 * This function is inserted by the compiler when a mutation
 * is detected during a foreach iteration. It gets called 
 * when a mutation occurs, and the enumerationMutationHandler
 * is enacted if it is set up. A fatal error occurs if a handler is not set up.
 * @param obj The object being mutated.
 */
OBJC_EXPORT void objc_enumerationMutation(id obj) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

weak原理:

/** 
 * This loads the object referenced by a weak pointer and returns it, after
 * retaining and autoreleasing the object to ensure that it stays alive
 * long enough for the caller to use it. This function would be used
 * anywhere a __weak variable is used in an expression.
 */
OBJC_EXPORT id objc_loadWeak(id *location)
    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);

/** 
 * This function stores a new value into a __weak variable. It would
 * be used anywhere a __weak variable is the target of an assignment.
 */
OBJC_EXPORT id objc_storeWeak(id *location, id obj) 
    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);

所有load方法的执行过程

入口方法_objc_load_imageobjc-os.mm里,prepare_load_methods负责读section找出class和category的所有load,放到静态列表变量里,确保先放superclass的,call_load_methods负责依次调用,先调class的,再调category的。

OBJC_EXPORT void _objc_load_image(HMODULE image, header_info *hinfo)
{
    prepare_load_methods(hinfo);
    call_load_methods();
}
void prepare_load_methods(const headerType *mhdr)
{
    size_t count, i;

    runtimeLock.assertWriting();

    classref_t *classlist = 
        _getObjc2NonlazyClassList(mhdr, &count);
    for (i = 0; i < count; i++) {
        schedule_class_load(remapClass(classlist[i]));
    }

    category_t **categorylist = _getObjc2NonlazyCategoryList(mhdr, &count);
    for (i = 0; i < count; i++) {
        category_t *cat = categorylist[i];
        Class cls = remapClass(cat->cls);
        if (!cls) continue;  // category for ignored weak-linked class
        realizeClass(cls);
        assert(cls->ISA()->isRealized());
        add_category_to_loadable_list(cat);
    }
}
GETSECT(_getObjc2NonlazyClassList,    classref_t,      "__objc_nlclslist");
GETSECT(_getObjc2NonlazyCategoryList, category_t *,    "__objc_nlcatlist");
static void schedule_class_load(Class cls)
{
    if (!cls) return;
    assert(cls->isRealized());  // _read_images should realize

    if (cls->data()->flags & RW_LOADED) return;

    // Ensure superclass-first ordering
    schedule_class_load(cls->superclass);

    add_class_to_loadable_list(cls);
    cls->setInfo(RW_LOADED); 
}
void call_load_methods(void)
{
    static bool loading = NO;
    bool more_categories;

    loadMethodLock.assertLocked();

    // Re-entrant calls do nothing; the outermost call will finish the job.
    if (loading) return;
    loading = YES;

    void *pool = objc_autoreleasePoolPush();

    do {
        // 1. Repeatedly call class +loads until there aren't any more
        while (loadable_classes_used > 0) {
            call_class_loads();
        }

        // 2. Call category +loads ONCE
        more_categories = call_category_loads();

        // 3. Run more +loads if there are classes OR more untried categories
    } while (loadable_classes_used > 0  ||  more_categories);

    objc_autoreleasePoolPop(pool);

    loading = NO;
}

objc-lockdebug.h/.mm

一堆lockdebug前缀的锁方法,可以检测死锁、锁没用对,等等。

objc-object.h

retain/release的各种实现,包括SUPPORT_RETURN_AUTORELEASE优化的黑技术。

static ALWAYS_INLINE bool 
callerAcceptsOptimizedReturn(const void *ra)
{
    // fd 03 1d aa    mov fp, fp
    if (*(uint32_t *)ra == 0xaa1d03fd) {
        return true;
    }
    return false;
}

objc-private.h/.mm

class AssociationsHashMap : public unordered_map<disguised_ptr_t, ObjectAssociationMap *, DisguisedPointerHash, DisguisedPointerEqual, AssociationsHashMapAllocator> {
    public:
        void *operator new(size_t n) { return ::malloc(n); }
        void operator delete(void *ptr) { ::free(ptr); }
    };

AssociationsHashMap *AssociationsManager::_map = NULL;

记录所有association到obj的key-value对。

objc-runtime-new.h/.mm

struct objc_class : objc_object {

各种标志。

static NXHashTable *realized_class_hash = nil;

static NXHashTable *realizedClasses(void)
{
    runtimeLock.assertLocked();

    // allocated in _read_images
    assert(realized_class_hash);

    return realized_class_hash;
}

实现类。

objc-sel.mm

SEL就是char*。存在静态变量namedSelectors里。

static NXMapTable *namedSelectors;

objc-sync.mm

@synchronized的实现。

int objc_sync_enter(id obj)
int objc_sync_exit(id obj)

用了递归锁recursive_mutex_t

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值