zoukankan      html  css  js  c++  java
  • Runtime

    Objective-C 

    Objective-C Objective-C Objc Runtime Objc Runtime Runtime C C 

    Runtime 

    1. C C runtime
    2. [object doSomething] (object) (doSomething) runtime

    Objective-C runtime Modern runtime Legacy runtime Modern Runtime 64 Mac OS X Apps iOS Apps Legacy Runtime 32 Mac OS X Apps 

    runtime Runtime 

     

    Class 

    Objective-C Class objc_class typedef struct objc_class *Class; 

    objc/runtime.h objc_class struct objc_class { 

      

      

    Search 

         

     

    Navigate...  Navigate... 

     

    Navigate... 

          

        Class isa  OBJC_ISA_AVAILABILITY;

    #if !__OBJC2__

        Class super_class

        const char *name

        long version

        long info

        long instance_size

        struct objc_ivar_list *ivars

        struct objc_method_list **methodLists

        struct objc_cache *cache

        struct objc_protocol_list *protocols

    #endif

    } OBJC2_UNAVAILABLE;

                        

    OBJC2_UNAVAILABLE; //
    OBJC2_UNAVAILABLE; //
    OBJC2_UNAVAILABLE; // 0 OBJC2_UNAVAILABLE; // OBJC2_UNAVAILABLE; // OBJC2_UNAVAILABLE; // OBJC2_UNAVAILABLE; // OBJC2_UNAVAILABLE; // 

    OBJC2_UNAVAILABLE; // 

    1. isa Objective-C Class isa metaClass( )
    2. super_class ( NSObject NSProxy) super_class NULL
    3. cache isa
      methodLists cache cache runtime cache cache methodLists

    4. version cache 

    NSArray *array = [[NSArray alloc] init];

     

    1. [NSArray alloc] NSArray +alloc NSObject
    2. NSObject +alloc NSArray isa NSArray
      +alloc cache
    3. -init NSArray cache
    4. [[NSArray alloc] init] cache

    objc_objectid objc_object (objc/objc.h) 

    struct objc_object {

        Class isa  OBJC_ISA_AVAILABILITY;

    };

    typedef struct objc_object *id;

    isa Objective-C isa Runtime selector 

    objc_object NSObject alloc allocWithZone: class_createInstance objc_object 

    id objc_object C++ C void * 

    objc_cache 

    objc_class cache objc_cache 

    struct objc_cache {

        unsigned int mask /* total = mask + 1 */

        unsigned int occupied

        Method buckets[1]

    }; 

                

    OBJC2_UNAVAILABLE;

    OBJC2_UNAVAILABLE;

    OBJC2_UNAVAILABLE;

    1. mask bucket Objective-C runtime selector AND (index = (mask & selector)) hash
    2. occupied bucket
    3. buckets Method mask+1 NULL bucket
      bucket

    (Meta Class) 

    ( ) NSArray *array = [NSArray array]; 

    +array NSArray NSArray objc_object isa isa +array isa objc_class meta-class 

    meta-class runtime meta-class 

    meta-class meta-class 

    meta-class isa Objective-C meta-class isa meta-class NSObject meta-class NSObject meta-class meta-class isa 

    objc_class super_class meta-class 

     

    NSObject meta-class meta-class 

    void TestMetaClass(id self, SEL _cmd) {

        NSLog(@"This objcet is %p", self);

        NSLog(@"Class is %@, super class is %@", [self class], [self superclass]);

        Class currentClass = [self class];

        for (int i = 0; i < 4; i++) {

            NSLog(@"Following the isa pointer %d times gives %p", i, currentClass);

            currentClass = objc_getClass((__bridge void *)currentClass);

        }

        NSLog(@"NSObject's class is %p", [NSObject class]);

        NSLog(@"NSObject's meta class is %p", objc_getClass((__bridge void *)[NSObject class]));

    }

    #pragma mark -

    @implementation Test

    - (void)ex_registerClassPair {

        Class newClass = objc_allocateClassPair([NSError class], "TestClass", 0);

        class_addMethod(newClass, @selector(testMetaClass), (IMP)TestMetaClass, "v@:");

        objc_registerClassPair(newClass);

        id instance = [[newClass alloc] initWithDomain:@"some domain" code:0 userInfo:nil];

        [instance performSelector:@selector(testMetaClass)];

    }

    @end 

    NSError TestClass testMetaClass TestMetaClass 

    2014-10-20 22:57:07.352 mountain[1303:41490] This objcet is 0x7a6e22b0

    2014-10-20 22:57:07.353 mountain[1303:41490] Class is TestStringClass, super class is NSError

    2014-10-20 22:57:07.353 mountain[1303:41490] Following the isa pointer 0 times gives 0x7a6e21b0

    2014-10-20 22:57:07.353 mountain[1303:41490] Following the isa pointer 1 times gives 0x0

    2014-10-20 22:57:07.353 mountain[1303:41490] Following the isa pointer 2 times gives 0x0

    2014-10-20 22:57:07.353 mountain[1303:41490] Following the isa pointer 3 times gives 0x0

    2014-10-20 22:57:07.353 mountain[1303:41490] NSObject's class is 0xe10000

    2014-10-20 22:57:07.354 mountain[1303:41490] NSObject's meta class is 0x0

    for objc_getClass isa NSObject meta-class 0x0 NSObject meta-class 

    class meta-class 

    runtime class objc object_ 

     

    objc_class runtime 

    (name) 

    //
    const char * class_getName ( Class cls ); 

    class_getName cls Nil (super_class)(meta-class) 

                  

    //
    Class class_getSuperclass ( Class cls ); 

    // Class
    BOOL class_isMetaClass ( Class cls ); 

    class_getSuperclass cls Nil cls Nil NSObject superclass class_isMetaClass cls YES cls Nil NO 

    (instance_size) 

    //
    size_t class_getInstanceSize ( Class cls ); 

    (ivars)objc_class ivars ivars Ivar( ) runtime 

    1. 

    //
    Ivar class_getInstanceVariable ( Class cls, const char *name ); 

    //
    Ivar class_getClassVariable ( Class cls, const char *name ); 

    //
    BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types ); 

    //
    Ivar * class_copyIvarList ( Class cls, unsigned int *outCount ); 

    class_getInstanceVariable name objc_ivar (Ivar) class_getClassVariable Objective-C Objective-C 

     

    Objective-C class_addIvar objc_allocateClassPair objc_registerClassPair 1<<alignment ivar log2(sizeof(pointer_type)) 

    class_copyIvarList objc_ivar outCount free() 

    2. // 

    objc_property_t class_getProperty ( Class cls, const char *name );

    //
    objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount ); 

    //
    BOOL class_addProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount ); 

    //
    void class_replaceProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount ); 

    ivars 

    3. MAC OS X runtime strong/weak 

    const uint8_t * class_getIvarLayout ( Class cls );

    void class_setIvarLayout ( Class cls, const uint8_t *layout );

    const uint8_t * class_getWeakIvarLayout ( Class cls );

    void class_setWeakIvarLayout ( Class cls, const uint8_t *layout );

    objc_registerClassPair (methodLists) 

                

    //
    BOOL class_addMethod ( Class cls, SEL name, IMP imp, const char *types ); 

    //
    Method class_getInstanceMethod ( Class cls, SEL name ); 

    //
    Method class_getClassMethod ( Class cls, SEL name ); 

    //
    Method * class_copyMethodList ( Class cls, unsigned int *outCount ); 

    //
    IMP class_replaceMethod ( Class cls, SEL name, IMP imp, const char *types ); 

    //
    IMP class_getMethodImplementation ( Class cls, SEL name );
    IMP class_getMethodImplementation_stret ( Class cls, SEL name ); 

    // selector
    BOOL class_respondsToSelector ( Class cls, SEL sel ); 

    class_addMethod NO method_setImplementation Objective-C C —self _cmd (IMP ) 

    void myMethodIMP(id self, SEL _cmd)

    {

        // implementation ....

    }

                                      

    types 

    class_getInstanceMethod class_getClassMethod class_copyMethodList 

    class_copyMethodList class_copyMethodList(object_getClass(cls), &count)( ) outCount free() 

    class_replaceMethod name class_addMethod name method_setImplementation 

    class_getMethodImplementation method_getImplementation(class_getInstanceMethod(cls, name)) runtime selector 

    class_respondsToSelector NSObject respondsToSelector: instancesRespondToSelector: (objc_protocol_list) 

                  

    //
    BOOL class_addProtocol ( Class cls, Protocol *protocol ); 

    //
    BOOL class_conformsToProtocol ( Class cls, Protocol *protocol ); 

    //
    Protocol * class_copyProtocolList ( Class cls, unsigned int *outCount ); 

    class_conformsToProtocol NSObject conformsToProtocol: class_copyProtocolList free() 

    (version) 

    //
    int class_getVersion ( Class cls ); 

    //
    void class_setVersion ( Class cls, int version ); 

     

    runtime CoreFoundation tool-free bridging Class objc_getFutureClass ( const char *name ); 

    void objc_setFutureClass ( Class cls, const char *name );

                   

    (Example) 

    //-----------------------------------------------------------

    // MyClass.h

    @interface MyClass : NSObject <NSCopying, NSCoding>

    @property (nonatomic, strong) NSArray *array;

    @property (nonatomic, copy) NSString *string;

    - (void)method1;

    - (void)method2;

    + (void)classMethod1;

    @end 

    //-----------------------------------------------------------

    // MyClass.m

    #import "MyClass.h"

    @interface MyClass () {

        NSInteger       _instance1;

        NSString    *   _instance2;

    }

    @property (nonatomic, assign) NSUInteger integer;

    - (void)method3WithArg1:(NSInteger)arg1 arg2:(NSString *)arg2;

    @end

    @implementation MyClass

    + (void)classMethod1 {

    }

    - (void)method1 {

        NSLog(@"call method method1");

    }

    - (void)method2 {

    }

    - (void)method3WithArg1:(NSInteger)arg1 arg2:(NSString *)arg2 {

        NSLog(@"arg1 : %ld, arg2 : %@", arg1, arg2);

    }

    @end 

    //-----------------------------------------------------------

    // main.h

    #import "MyClass.h"

    #import "MySubClass.h"

    #import <objc/runtime.h>

    int main(int argc, const char * argv[]) {

        @autoreleasepool {

            MyClass *myClass = [[MyClass alloc] init];

            unsigned int outCount = 0;

            Class cls = myClass.class;

    //
    NSLog(@"class name: %s", class_getName(cls)); 

            NSLog(@"==========================================================");

    //
    NSLog(@"super class name: %s", class_getName(class_getSuperclass(cls))); NSLog(@"=========================================================="); 

    //
    NSLog(@"MyClass is %@ a meta-class", (class_isMetaClass(cls) ? @"" : @"not")); NSLog(@"=========================================================="); 

            Class meta_class = objc_getMetaClass(class_getName(cls));

            NSLog(@"%s's meta-class is %s", class_getName(cls), class_getName(meta_class));

            NSLog(@"==========================================================");

    //
    NSLog(@"instance size: %zu", class_getInstanceSize(cls)); NSLog(@"=========================================================="); 

    //
    Ivar *ivars = class_copyIvarList(cls, &outCount); for (int i = 0; i < outCount; i++) { 

                Ivar ivar = ivars[i];

                NSLog(@"instance variable's name: %s at index: %d", ivar_getName(ivar), i);

            }

            free(ivars);

            Ivar string = class_getInstanceVariable(cls, "_string");

            if (string != NULL) {

                NSLog(@"instace variable %s", ivar_getName(string));

            }

            NSLog(@"==========================================================");

    //
    objc_property_t * properties = class_copyPropertyList(cls, &outCount); for (int i = 0; i < outCount; i++) { 

                objc_property_t property = properties[i];

                NSLog(@"property's name: %s", property_getName(property));

            }

            free(properties);

            objc_property_t array = class_getProperty(cls, "array");

            if (array != NULL) {

                NSLog(@"property %s", property_getName(array));

            }

            NSLog(@"==========================================================");

    //
    Method *methods = class_copyMethodList(cls, &outCount); for (int i = 0; i < outCount; i++) { 

                Method method = methods[i];

                NSLog(@"method's signature: %s", method_getName(method));

            }

            free(methods);

            Method method1 = class_getInstanceMethod(cls, @selector(method1));

            if (method1 != NULL) {

                NSLog(@"method %s", method_getName(method1));

            }

            Method classMethod = class_getClassMethod(cls, @selector(classMethod1));

            if (classMethod != NULL) {

                NSLog(@"class method : %s", method_getName(classMethod));

            }

            NSLog(@"MyClass is%@ responsd to selector: method3WithArg1:arg2:", class_respondsToSelector(cls, @selector(method3WithArg1:arg2:)) ? @

            IMP imp = class_getMethodImplementation(cls, @selector(method1));

            imp();

            NSLog(@"==========================================================");

    //
    Protocol * __unsafe_unretained * protocols = class_copyProtocolList(cls, &outCount); Protocol * protocol;
    for (int i = 0; i < outCount; i++) { 

                protocol = protocols[i];

                NSLog(@"protocol name: %s", protocol_getName(protocol));

            }

            NSLog(@"MyClass is%@ responsed to protocol %s", class_conformsToProtocol(cls, protocol) ? @"" : @" not", protocol_getName(protocol));

            NSLog(@"==========================================================");

        }

    return 0; } 

     

    2014-10-22 19:41:37.452 RuntimeTest[3189:156810] class name: MyClass

    2014-10-22 19:41:37.453 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] super class name: NSObject

    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] MyClass is not a meta-class

    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.454 RuntimeTest[3189:156810] MyClass's meta-class is MyClass

    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance size: 48

    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _instance1 at index: 0

    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _instance2 at index: 1

    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _array at index: 2

    2014-10-22 19:41:37.455 RuntimeTest[3189:156810] instance variable's name: _string at index: 3

    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] instance variable's name: _integer at index: 4

    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] instace variable _string

    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] property's name: array

    2014-10-22 19:41:37.463 RuntimeTest[3189:156810] property's name: string

    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] property's name: integer

    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] property array

    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] method's signature: method1

    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] method's signature: method2

    2014-10-22 19:41:37.464 RuntimeTest[3189:156810] method's signature: method3WithArg1:arg2:

    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: integer

    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: setInteger:

    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: array

    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: string

    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: setString:

    2014-10-22 19:41:37.465 RuntimeTest[3189:156810] method's signature: setArray:

    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] method's signature: .cxx_destruct

    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] method method1

    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] class method : classMethod1

    2014-10-22 19:41:37.466 RuntimeTest[3189:156810] MyClass is responsd to selector: method3WithArg1:arg2:

    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] call method method1

    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] ==========================================================

    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] protocol name: NSCopying

    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] protocol name: NSCoding

    2014-10-22 19:41:37.467 RuntimeTest[3189:156810] MyClass is responsed to protocol NSCoding

    2014-10-22 19:41:37.468 RuntimeTest[3189:156810] ==========================================================

     

    runtime 

     

                   

    //
    Class objc_allocateClassPair ( Class superclass, const char *name, size_t extraBytes ); 

    //
    void objc_disposeClassPair ( Class cls ); 

    // objc_allocateClassPair void objc_registerClassPair ( Class cls ); 

    objc_allocateClassPair superclass Nil extraBytes 0 ivars 

    objc_allocateClassPair class_addMethod class_addIvar objc_registerClassPair 

    objc_disposeClassPair 

                                                 

    Class cls = objc_allocateClassPair(MyClass.class, "MySubClass", 0);

    class_addMethod(cls, @selector(submethod1), (IMP)imp_submethod1, "v@:");

    class_replaceMethod(cls, @selector(method1), (IMP)imp_submethod1, "v@:");

    class_addIvar(cls, "_ivar1", sizeof(NSString *), log(sizeof(NSString *)), "i");

    objc_property_attribute_t type = {"T", "@"NSString""};

    objc_property_attribute_t ownership = { "C", "" };

    objc_property_attribute_t backingivar = { "V", "_ivar1"};

    objc_property_attribute_t attrs[] = {type, ownership, backingivar};

    class_addProperty(cls, "property2", attrs, 3);

    objc_registerClassPair(cls);

    id instance = [[cls alloc] init];

    [instance performSelector:@selector(submethod1)];

    [instance performSelector:@selector(method1)];

     

    2014-10-23 11:35:31.006 RuntimeTest[3800:66152] run sub method 1

    2014-10-23 11:35:31.006 RuntimeTest[3800:66152] run sub method 1

     

                

    //
    id class_createInstance ( Class cls, size_t extraBytes ); 

    //
    id objc_constructInstance ( Class cls, void *bytes ); 

    //
    void * objc_destructInstance ( id obj ); 

    class_createInstance extraBytes ARC 

    class_createInstance +alloc class_createInstance NSString 

    id theObject = class_createInstance(NSString.class, sizeof(unsigned));

    id str1 = [theObject init];

    NSLog(@"%@", [str1 class]);

    id str2 = [[NSString alloc] initWithString:@"test"];

    NSLog(@"%@", [str2 class]);

     

    2014-10-23 12:46:50.781 RuntimeTest[4039:89088] NSString

    2014-10-23 12:46:50.781 RuntimeTest[4039:89088] __NSCFConstantString

    class_createInstance NSString __NSCFConstantString objc_constructInstance (bytes) objc_destructInstance 

     

                                                                       

                  

    1. // 

    id object_copy ( id obj, size_t size );

    //
    id object_dispose ( id obj ); 

    A B B A B A A B B B A 

    NSObject *a = [[NSObject alloc] init];

    id newB = object_copy(a, class_getInstanceSize(MyClass.class));

    object_setClass(newB, MyClass.class);

    object_dispose(a);

    2. // 

    Ivar object_setInstanceVariable ( id obj, const char *name, void *value );

    //
    Ivar object_getInstanceVariable ( id obj, const char *name, void **outValue ); 

    // void * object_getIndexedIvars ( id obj ); 

    //
    id object_getIvar ( id obj, Ivar ivar ); 

    //
    void object_setIvar ( id obj, Ivar ivar, id value ); 

    Ivar object_getIvar object_getInstanceVariable object_setIvar object_setInstanceVariable 3. 

    //
    const char * object_getClassName ( id obj ); 

    //
    Class object_getClass ( id obj ); 

  • 相关阅读:
    ISO/IEC 9899:2011 条款6.6——常量表达式
    ISO/IEC 9899:2011 条款6.5.17——逗号操作符
    ISO/IEC 9899:2011 条款6.5.16——赋值操作符
    ISO/IEC 9899:2011 条款6.5.15——条件操作符
    ISO/IEC 9899:2011 条款6.5.10——按位与操作符
    ISO/IEC 9899:2011 条款6.5.9——相等操作符
    php正则表达式入门-常用语法格式
    史上最全PHP正则表达式实例汇总
    mysql数据库TINYINT取值范围详解
    Sql Server删除数据表中重复记录 三种方法
  • 原文地址:https://www.cnblogs.com/eyxForWork/p/5717062.html
Copyright © 2011-2022 走看看