RunTime的一些知识点之对象二
2017-05-18 本文已影响55人
bonoCat
RunTime的一些知识点之对象二
主要是对文档的翻译,希望能有一个比较全面的理解
class 是什么?
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class 父类 OBJC2_UNAVAILABLE;
const char *name 名称 OBJC2_UNAVAILABLE;
long version 版本 OBJC2_UNAVAILABLE;
long info 信息 OBJC2_UNAVAILABLE;
long instance_size 内存大小 OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars 实例变量列表 OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists 方法列表 OBJC2_UNAVAILABLE;
struct objc_cache *cache 缓存 OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols 协议列表 OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
class 是一个结构体,包含super_class、name、version、info、instance_size、ivars、methodLists、cache、protocols
能做些什么?
对象copy
OBJC_EXPORT id object_copy(id obj, size_t size)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
OBJC_ARC_UNAVAILABLE;
对象销毁(ARC中不能使用)
OBJC_EXPORT id object_dispose(id obj)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
OBJC_ARC_UNAVAILABLE;
获取指定对象的class
OBJC_EXPORT Class object_getClass(id obj)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
设置指定对象的类
OBJC_EXPORT Class object_setClass(id obj, Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
判断是否为class对象
OBJC_EXPORT BOOL object_isClass(id obj)
OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0);
实例说明
Engineer *person = [[Engineer alloc] init];
NSLog(@"%@", object_isClass([Engineer class]) ? @"1" : @"0"); // 0
NSLog(@"%@", object_isClass(person) ? @"1" : @"0"); // 1
获取实例变量值
/*
* @note \c object_getIvar is faster than \c object_getInstanceVariable if the Ivar
* for the instance variable is already known.
*/
OBJC_EXPORT id object_getIvar(id obj, Ivar ivar)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
/// 获取实例变量
Ivar ivar = class_getInstanceVariable([self class], "_name");
object_getIvar(self, ivar);
设置实例变量的值
/*
* @note Instance variables with known memory management (such as ARC strong and weak)
* use that memory management. Instance variables with unknown memory management
* are assigned as if they were unsafe_unretained.
* unsafe_unretained 会造成未知的内存管理问题
* @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar
* for the instance variable is already known.
*/
OBJC_EXPORT void object_setIvar(id obj, Ivar ivar, id value)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
OBJC_EXPORT void object_setIvarWithStrongDefault(id obj, Ivar ivar, id value)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0);
/// 速度慢
OBJC_EXPORT Ivar object_setInstanceVariable(id obj, const char *name, void *value)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
OBJC_ARC_UNAVAILABLE;
OBJC_EXPORT Ivar object_setInstanceVariableWithStrongDefault(id obj, const char *name, void *value)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0)
OBJC_ARC_UNAVAILABLE;
OBJC_EXPORT Ivar object_getInstanceVariable(id obj, const char *name, void **outValue)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
OBJC_ARC_UNAVAILABLE;
获取 class MetaClass
// Returns the class of an object.
OBJC_EXPORT Class object_getClass(id obj)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
// Returns the class definition of a specified class.
OBJC_EXPORT Class objc_getClass(const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
/// 获取元类
OBJC_EXPORT Class objc_getMetaClass(const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
实例说明
/// 定义一个Engineer的class
Class className = objc_getClass("Engineer");
/// 是否为class
if (object_isClass(className)) {
/// 获取 class 的名称
const char *name_ = object_getClassName([[className alloc] init]);
/// 得到 Engineer
NSLog(@"%s", name_);
}
元类理解
/* metaClass 是类的类
当你向一个对象发送消息时,runtime会在这个对象所属的那个类的方法列表中查找。
当你向一个类发送消息时,runtime会在这个类的meta-class的方法列表中查找。
meta-class之所以重要,是因为它存储着一个类的所有类方法。每个类都会有一个单独的meta-class,因为每个类的类方法基本不可能完全相同。
保证设计的完整性, metaclass 也是对象 也就有 isa
*/
NSLog(@"元类 %p", objc_getMetaClass("Engineer"));
NSLog(@"元类 %p", object_getClass([[Engineer class] class]));
// 2017-05-18 16:36:06.259 RunTime[19555:203675] 元类 0x108d5a188
// 2017-05-18 16:36:07.474 RunTime[19555:203675] 元类 0x108d5a188
/*
* objc_getClass 不但执行这个方法,还会判断是否注册
* objc_lookUpClass 直接执行
*/
OBJC_EXPORT Class objc_lookUpClass(const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
/*
* @note This function is the same as \c objc_getClass, but kills the process if the class is not found.
* @note This function is used by ZeroLink, where failing to find a class would be a compile-time link error without ZeroLink.
*/
OBJC_EXPORT Class objc_getRequiredClass(const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);