JavaScript

iOS Runtime详解

2016-03-02  本文已影响99人  AKyS佐毅

1、runtime(运行时机制)是什么

2、runtime知识图谱

3、runtime数据结构

struct objc_object {
   private:
       isa_t isa;
   
   public:
   
       // ISA() assumes this is NOT a tagged pointer object
       Class ISA();
   
       // getIsa() allows this to be a tagged pointer object
       Class getIsa();
   
       // initIsa() should be used to init the isa of new objects only.
       // If this object already has an isa, use changeIsa() for correctness.
       // initInstanceIsa(): objects with no custom RR/AWZ
       // initClassIsa(): class objects
       // initProtocolIsa(): protocol objects
       // initIsa(): other objects
       void initIsa(Class cls /*indexed=false*/);
       void initClassIsa(Class cls /*indexed=maybe*/);
       void initProtocolIsa(Class cls /*indexed=maybe*/);
       void initInstanceIsa(Class cls, bool hasCxxDtor);
   
       // changeIsa() should be used to change the isa of existing objects.
       // If this is a new object, use initIsa() for performance.
       Class changeIsa(Class newCls);
   
       bool hasIndexedIsa();
       bool isTaggedPointer();
       bool isClass();
   
       // object may have associated objects?
       bool hasAssociatedObjects();
       void setHasAssociatedObjects();
   
       // object may be weakly referenced?
       bool isWeaklyReferenced();
       void setWeaklyReferenced_nolock();
   
       // object may have -.cxx_destruct implementation?
       bool hasCxxDtor();
   
       // Optimized calls to retain/release methods
       id retain();
       void release();
       id autorelease();
   
       // Implementations of retain/release methods
       id rootRetain();
       bool rootRelease();
       id rootAutorelease();
       bool rootTryRetain();
       bool rootReleaseShouldDealloc();
       uintptr_t rootRetainCount();
   
       // Implementation of dealloc methods
       bool rootIsDeallocating();
       void clearDeallocating();
       void rootDealloc();
   
   private:
       void initIsa(Class newCls, bool indexed, bool hasCxxDtor);
   
       // Slow paths for inline control
       id rootAutorelease2();
       bool overrelease_error();
   
   #if SUPPORT_NONPOINTER_ISA
       // Unified retain count manipulation for nonpointer isa
       id rootRetain(bool tryRetain, bool handleOverflow);
       bool rootRelease(bool performDealloc, bool handleUnderflow);
       id rootRetain_overflow(bool tryRetain);
       bool rootRelease_underflow(bool performDealloc);
   
       void clearDeallocating_slow();
   
       // Side table retain count overflow for nonpointer isa
       void sidetable_lock();
       void sidetable_unlock();
   
       void sidetable_moveExtraRC_nolock(size_t extra_rc, bool isDeallocating, bool weaklyReferenced);
       bool sidetable_addExtraRC_nolock(size_t delta_rc);
       size_t sidetable_subExtraRC_nolock(size_t delta_rc);
       size_t sidetable_getExtraRC_nolock();
   #endif
   
       // Side-table-only retain count
       bool sidetable_isDeallocating();
       void sidetable_clearDeallocating();
   
       bool sidetable_isWeaklyReferenced();
       void sidetable_setWeaklyReferenced_nolock();
   
       id sidetable_retain();
       id sidetable_retain_slow(SideTable& table);
   
       uintptr_t sidetable_release(bool performDealloc = true);
       uintptr_t sidetable_release_slow(SideTable& table, bool performDealloc = true);
   
       bool sidetable_tryRetain();
   
       uintptr_t sidetable_retainCount();
   #if DEBUG
       bool sidetable_present();
   #endif
};
struct objc_class : objc_object {
    Class superclass;
    const char *name;
    uint32_t version;
    uint32_t info;
    uint32_t instance_size;
    struct old_ivar_list *ivars;
    struct old_method_list **methodLists;
    Cache cache;
    struct old_protocol_list *protocols;
    // CLS_EXT only
    const uint8_t *ivar_layout;
    struct old_class_ext *ext;

    void setInfo(uint32_t set) {
        OSAtomicOr32Barrier(set, (volatile uint32_t *)&info);
    }

    void clearInfo(uint32_t clear) {
        OSAtomicXor32Barrier(clear, (volatile uint32_t *)&info);
    }


    // set and clear must not overlap
    void changeInfo(uint32_t set, uint32_t clear) {
        assert((set & clear) == 0);

        uint32_t oldf, newf;
        do {
            oldf = this->info;
            newf = (oldf | set) & ~clear;
        } while (!OSAtomicCompareAndSwap32Barrier(oldf, newf, (volatile int32_t *)&info));
    }

    bool hasCxxCtor() {
        // set_superclass propagates the flag from the superclass.
        return info & CLS_HAS_CXX_STRUCTORS;
    }

    bool hasCxxDtor() {
        return hasCxxCtor();  // one bit for both ctor and dtor
    }

    bool hasCustomRR() { 
        return true;
    }
    void setHasCustomRR(bool = false) { }
    void setHasDefaultRR() { }
    void printCustomRR(bool) { }

    bool hasCustomAWZ() { 
        return true;
    }
    void setHasCustomAWZ(bool = false) { }
    void setHasDefaultAWZ() { }
    void printCustomAWZ(bool) { }

    bool instancesHaveAssociatedObjects() {
        return info & CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS;
    }

    void setInstancesHaveAssociatedObjects() {
        setInfo(CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS);
    }

    bool shouldGrowCache() {
        return info & CLS_GROW_CACHE;
    }

    void setShouldGrowCache(bool grow) {
        if (grow) setInfo(CLS_GROW_CACHE);
        else clearInfo(CLS_GROW_CACHE);
    }

    bool shouldFinalizeOnMainThread() {
        return info & CLS_FINALIZE_ON_MAIN_THREAD;
    }

    void setShouldFinalizeOnMainThread() {
        setInfo(CLS_FINALIZE_ON_MAIN_THREAD);
    }

    // +initialize bits are stored on the metaclass only
    bool isInitializing() {
        return getMeta()->info & CLS_INITIALIZING;
    }

    // +initialize bits are stored on the metaclass only
    void setInitializing() {
        getMeta()->setInfo(CLS_INITIALIZING);
    }

    // +initialize bits are stored on the metaclass only
    bool isInitialized() {
        return getMeta()->info & CLS_INITIALIZED;
    }

    // +initialize bits are stored on the metaclass only
    void setInitialized() {
        getMeta()->changeInfo(CLS_INITIALIZED, CLS_INITIALIZING);
    }

    bool isLoadable() {
        // A class registered for +load is ready for +load to be called
        // if it is connected.
        return isConnected();
    }

    IMP getLoadMethod();

    bool isFuture();

    bool isConnected();

    const char *mangledName() { return name; }
    const char *demangledName() { return name; }
    const char *nameForLogging() { return name; }

    bool isMetaClass() {
        return info & CLS_META;
    }

    // NOT identical to this->ISA() when this is a metaclass
    Class getMeta() {
        if (isMetaClass()) return (Class)this;
        else return this->ISA();
    }

    // May be unaligned depending on class's ivars.
    uint32_t unalignedInstanceSize() {
        return instance_size;
    }

    // Class's ivar size rounded up to a pointer-size boundary.
    uint32_t alignedInstanceSize() {
        return (unalignedInstanceSize() + WORD_MASK) & ~WORD_MASK;
    }

    size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }

};
struct method_t {
    SEL name;
    const char *types;
    IMP imp;

    struct SortBySELAddress :
        public std::binary_function<const method_t&,
                                    const method_t&, bool>
    {
        bool operator() (const method_t& lhs,
                         const method_t& rhs)
        { return lhs.name < rhs.name; }
    };
};

4、类对象与元类对象&消息传递相关面试问题

为什么会有元类呢?

消息传递的机制

而实际消息当一个方法调用的消息发出后,消息传递的机制为:

5、消息转发流程

关于消息转发的流程,其实是系统给的一个消息再利用的过程,当消息传递流程中没有方法来响应此消息时,开发者可通过重写以下这四个方法来实现消息转发的过程,以及去让计算机做相应的工作。

若返回YES,则表明消息已处理,结束流程,若返回NO则进行下一个方法的调用

此方法可以返回转发消息的目标,若返回为nil则调用下一个方法

此方法可以返回方法的签名,若返回nil则直接抛出异常,表明方法函数体指针无法被找到,若返回方法签名,则调用下一个方法

此方法内部会决定是否已处理方法,如果到这个方法也没法处理,则抛出异常,报错

以上四个方法是系统留给开发者处理消息转发的入口,开发者可以通过重写以上四个方法来手动处理消息转发的流程。

image image

6、Method-Swizzling

image image

7、动态添加方法

image

8、动态方法解析

上一篇下一篇

猜你喜欢

热点阅读