iOS-9.函数签名和Type Encodings

2,219 阅读2分钟

ios底层文章汇总

1.imp与SEL 的关系

SEL : 方法编号,相当于书本目录的名称

IMP : 函数指针地址,相当于书本目录的⻚码

1:首先需要找到书本的什么内容 (sel 目录里面的名称)

2:通过名称找到对应的本⻚码 (imp)

3:通过⻚码去定位具体的内容

2.Type Encodings

在Xcode下使用快捷键shift+command+0,搜索ivar_getTypeEncoding,点击Type Encodings可以链接到苹果的官方文档

Objective-C type encodings

也可以通过@encode()函数获取类型的编码

void lgTypes(){
    NSLog(@"char --> %s",@encode(char));
    NSLog(@"int --> %s",@encode(int));
    NSLog(@"short --> %s",@encode(short));
    NSLog(@"long --> %s",@encode(long));
    NSLog(@"long long --> %s",@encode(long long));
    NSLog(@"unsigned char --> %s",@encode(unsigned char));
    NSLog(@"unsigned int --> %s",@encode(unsigned int));
    NSLog(@"unsigned short --> %s",@encode(unsigned short));
    NSLog(@"unsigned long --> %s",@encode(unsigned long long));
    NSLog(@"float --> %s",@encode(float));
    NSLog(@"bool --> %s",@encode(bool));
    NSLog(@"void --> %s",@encode(void));
    NSLog(@"char * --> %s",@encode(char *));
    NSLog(@"id --> %s",@encode(id));
    NSLog(@"Class --> %s",@encode(Class));
    NSLog(@"SEL --> %s",@encode(SEL));
    int array[] = {1,2,3};
    NSLog(@"int[] --> %s",@encode(typeof(array)));
    typedef struct person{
        char *name;
        int age;
    }Person;
    NSLog(@"struct --> %s",@encode(Person));
    
    typedef union union_type{
        char *name;
        int a;
    }Union;
    NSLog(@"union --> %s",@encode(Union));

    int a = 2;
    int *b = {&a};
    NSLog(@"int[] --> %s",@encode(typeof(b)));
}

3.函数签名

iOS-Objc类结构解析,获取method列表时,可以看到函数的types是"v16@0:8",这个types就是函数签名.

"v16@0:8解析:

v : 返回值类型为void;

16: 函数的传入的所有参数的字节数之和为16

@:参数类型 为id型

0:前面的参数起始的字节位置(从0开始)

: 参数类型为 sel

8:前面的参数起始的字节位置(从8开始)

"v16@0:8"的含义为: 表示一个函数,返回值为void,共有两个参数,一个为id类型,一个为sel类型,两个参数个需要8个字节存储

4.属性的签名

commad + shift + 0 => 搜索'property_getAttributes'

T@"NSString",C,N,V_nickname解析:

T@"NSString" : T是type. @"NSString" 是具体的type类型

C: copy

N: nonatomic

V_nickname: V代表verible变量

其他类型的解析参考:苹果官方文档

5. 遍历某个对象的成员变量

#pragma mark --遍历某个对象的成员变量
void printClassAllProperties(Class cls){
    unsigned int outCount = 0;
    objc_property_t *properties =class_copyPropertyList(cls, &outCount);
    NSMutableArray *propertiesArray = [NSMutableArray arrayWithCapacity:outCount];
    for (int i = 0; i < outCount; i++) {
        //objc_property_t属性类型
        objc_property_t property = properties[i];
        //获取属性的名称
        const char *cName = property_getName(property);
        NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
        [propertiesArray addObject:name];
        NSLog(@"属性:%@:%s",name,property_getAttributes(property));
        /*
          属性:nickname:T@"NSString",C,N,V_nickname
          属性:age:Tq,N,V_age
          属性:sex:TB,N,V_sex
         */
        
    }
    free(properties);
}