Runtime 成员变量、属性及方法相关函数

1.成员变量函数

获取成员变量信息的有三个函数:ivar_getNameivar_getTypeEncodingivar_getOffset。这几个函数都会接收一个 Ivar 类型的参数,这个是共性。

1.1 ivar_getName

OBJC_EXPORT const char * _Nullable
ivar_getName(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

获取实例变量的名字。返回值是一个c的字符串。

1.2 ivar_getTypeEncoding

OBJC_EXPORT const char * _Nullable
ivar_getTypeEncoding(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

获取实例变量的类型,这里大致写几个类型。

Code Meaning
c A char
i An int
f A float
d A double
v A void

详细的类型看一下官方解释

1.3 ivar_getOffset

OBJC_EXPORT ptrdiff_t
ivar_getOffset(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

获取成员变量的内存偏移量。详情请自行搜索。

这里请注意 ptrdiff_t 这个返回值类型,在 runtime 暴露出的函数中,没有任何一个函数使用到了 ptrdiff_t 类型的参数,姑且可以认为 ivar_getOffset 这个函数对我们没有什么用处。

查看 runtime 源码的话还是可以看到很多地方有使用到这个类型,但这不在说明之中,只需要记住这反应了一个内存偏移量,有印象即可。

2. 属性函数

获取属性信息的函数有四个函数:property_getNameproperty_getAttributesproperty_copyAttributeListproperty_copyAttributeValue 。这几个函数都会接收一个objc_property_t 类型的参数,这个是共性。

2.1 property_getName

OBJC_EXPORT const char * _Nonnull
property_getName(objc_property_t _Nonnull property) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回属性的名称

2.2 property_getAttributes

OBJC_EXPORT const char * _Nullable
property_getAttributes(objc_property_t _Nonnull property) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回的是属性的信息, 举一个小例子:

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, assign) CGFloat weight;
@property (atomic, assign) CGFloat height; // 注意这里是atomic
复制代码

对应的属性信息为:

T@"NSString",C,N,V_name
TQ,N,V_age
Td,N,V_weight
Td,V_height
复制代码

正常人都看不懂,但看过官方解释之后,相信正常人都能看懂了。

//T@"NSString",C,N,V_name
//T 类型
//C copy
//N nonatomic
//V 实例变量
复制代码

2.3 property_copyAttributeList

OBJC_EXPORT objc_property_attribute_t * _Nullable
property_copyAttributeList(objc_property_t _Nonnull property,
                           unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);
复制代码

property_copyAttributeList 获取的是属性所有描述信息的数组,需要遍历取出信息,而 property_getAttributes 则是已经把属性的描述信息拼接成 c 字符串了。

感兴趣的可以自己试试下面的代码。

objc_property_t *propertyList = class_copyPropertyList([CZPerson class], &outCount);
for (unsigned int i = 0; i < outCount; i++) {
    objc_property_t property = propertyList[i];
    const char* propertyAttributes = property_getAttributes(property);
    NSLog(@"property_getAttributes信息:%@",[NSString stringWithUTF8String:propertyAttributes]);
    
    unsigned int count = 0;
    objc_property_attribute_t *array = property_copyAttributeList(property, &count);
    for (unsigned j = 0; j < count; j++) {
        objc_property_attribute_t t = array[j];
        NSLog(@"property_copyAttributeList信息:%s 值:%s", t.name, t.value);
    }
    NSLog(@"------------------属性分割线------------------");
}
free(propertyList);
复制代码

2.4 property_copyAttributeValue

OBJC_EXPORT char * _Nullable
property_copyAttributeValue(objc_property_t _Nonnull property,
                            const char * _Nonnull attributeName)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);
复制代码

返回目标属性中attribute的值。attributeName 的值就是上面的 TCNV,那些你看不懂的。

3. 方法

和方法相关的函数有11个,太多了就不列举了。这几个函数都会接收一个 Method 类型的参数,这个是共性。

3.1 method_getName

OBJC_EXPORT SEL _Nonnull
method_getName(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回 SEL 形式的方法名称。c字符串形式的方法名称需要使用

sel_getName(method_getName(Method m))
复制代码

3.2 method_getImplementation

OBJC_EXPORT IMP _Nonnull
method_getImplementation(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回方法的实现。

3.3 method_getTypeEncoding

OBJC_EXPORT const char * _Nullable
method_getTypeEncoding(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回方法参数和返回类型的字符串

3.4 method_getNumberOfArguments

OBJC_EXPORT unsigned int
method_getNumberOfArguments(Method _Nonnull m)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
复制代码

返回参数个数

3.5 method_copyReturnType

OBJC_EXPORT char * _Nonnull
method_copyReturnType(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回返回值的类型

3.6 method_copyArgumentType

OBJC_EXPORT char * _Nullable
method_copyArgumentType(Method _Nonnull m, unsigned int index) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回单个参数的类型。index表示第几个参数

3.7 method_getReturnType

OBJC_EXPORT void
method_getReturnType(Method _Nonnull m, char * _Nonnull dst, size_t dst_len) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回返回值的类型

3.8 method_getArgumentType

OBJC_EXPORT void
method_getArgumentType(Method _Nonnull m, unsigned int index, 
                       char * _Nullable dst, size_t dst_len) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回单个参数的类型。

3.9 method_getDescription

OBJC_EXPORT struct objc_method_description * _Nonnull
method_getDescription(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回方法的描述

3.10 method_setImplementation

OBJC_EXPORT IMP _Nonnull
method_setImplementation(Method _Nonnull m, IMP _Nonnull imp) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

返回方法的实现

3.11 method_exchangeImplementations

OBJC_EXPORT void
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码

交换方法的实现

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享