虽然现在swift语言的使用越来越广泛了,但作为iOS开发20多年御用开发语言的Objective-C仍有着相当大的用户群,现在要从事iOS开发,不会Objective-C根本就不能称之为iOS开发者。今天小编就为大家介绍一下Objective-C Class Ivar Layout的相关应用。
当定义一个类的实例变量的时候,可以指定其修饰符:
@interface Sark: NSObject {
__strong id _gayFriend; //无修饰符的对象默认会加__strong
__weak id _girlFriend;
__unsafe_unretained id _company;
}
@end
这使得ivar (instance variable)可以像属性一样在ARC下进行正确的引用计数管理。那么问题来了,假如这个类是动态生成的:
Class class =objc_allocateClassPair(NSObject.class, "Sark", 0);
class_addIvar(class,"_gayFriend", sizeof(id), log2(sizeof(id)), @encode(id));
class_addIvar(class,"_girlFriend", sizeof(id), log2(sizeof(id)), @encode(id));
class_addIvar(class,"_company", sizeof(id), log2(sizeof(id)), @encode(id));
objc_registerClassPair(class);
该如何像上面一样来添加ivar的属性修饰符呢?刨根问底了一下,发现ivar的修饰信息存放在了Class的Ivar Layout中:
structclass_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout; // <-记录了哪些是strong的ivar
const char * name;
const method_list_t * baseMethods;
const protocol_list_t * baseProtocols;
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout; // <-记录了哪些是weak的ivar
const property_list_t *baseProperties;
};
ivarLayout和weakIvarLayout分别记录了哪些ivar是strong或是weak,都未记录的就是基本类型和__unsafe_unretained的对象类型。
这两个值可以通过runtime提供的几个API来访问:
const uint8_t*class_getIvarLayout(Class cls)
const uint8_t*class_getWeakIvarLayout(Class cls)
voidclass_setIvarLayout(Class cls, const uint8_t *layout)
voidclass_setWeakIvarLayout(Class cls, const uint8_t *layout)
但我们几乎没可能用到这几个API,IvarLayout的值由runtime确定,没必要关心它的存在,但为了解决上述问题,我们试着破解了IvarLayout的编码方式。
举个例子说明,若类定义为:
@interface Foo :NSObject {
__strong id ivar0;
__weak id ivar1;
__weak id ivar2;
}
@end
则储存strong ivar的ivarLayout的值为0x012000
储存weak ivar的weakIvarLayout的值为0x1200
一个uint8_t在16进制下是两位,所以编码的值每两位一对儿,以上面的ivarLayout为例:
前两位01表示有0个非strong对象和1个strong对象
之后两位20表示有2个非strong对象和0个strong对象
最后两位00为结束符,就像cstring的\0一样
同理,上面的weakIvarLayout:
前两位12表示有1个非weak对象和接下来连续2个weak对象
00结束符
这样,用两个layout编码值就可以排查出一个ivar是属于strong还是weak的,若都没有找到,就说明这个对象是unsafe_unretained.
以上就是Objective-C Class Ivar Layout的使用方法,这个知识点在iOS开发中还是比较重要的,看完上面的介绍,大家可以自己动手操作下,加深相关知识的掌握。
推荐学习:《objective-c基础教程》
原文链接:http://www.jianshu.com/p/d07133264506
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。