这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战缓存
在WWDC关于runtime里面关于类的优化里面提到了clean memory
,dirty memory
markdown
class_ro_t
是只读的,属于Clean Memory
Dirty Memory
,由于运行时会写入新的数据,例如:方法缓存Dirty Memory
是类数据被分为两部分的缘由Dirty Memory
比Clean Memory
更昂贵,由于在进程运行的整个过程当中,都须要被保留。经过分离出那些永远不会改变的数据,将大部分的类数据存储为Clean Memory
。 类结构一经使用就会变成Dirty Memory
,由于运行时会向他写入新的数据,例如建立一个新的方法缓存并从类中指向它。因此class_rw_t
出现了,它能够读写类的继承关系,跟踪类的方法,属性,协议等,单只有大约10%的类会去修改它的方法,因此class_rw_ext_t
出现了,90%内将不须要class_rw_ext_t
,这能节省class_rw_t
一半的空间。以下图app
在iOS5以前,定义成员变量是在大括号里定义,同时用了@property
声明,并且还在@implementation中使用@synthesize方法。缘由是苹果将默认编译器从GCC转换为LLVM(low level virtual machine),才再也不须要为属性声明实例变量了。 在没有更改以前,属性的正常写法须要成员变量+@property+@synthesize成员便利那个三个步骤。更换为LLVM以后,编译器在编译过程当中发现没有新的实例变量后,就会生成一个下划线开头的实例变量。所以如今部门没必要再声明一个实例变量。 如今@property声明的属性不单单给咱们生成一个_类型的成员变量,同时也会生成setter/getter方法。ide
NSObject
类型NSString
为常量类型,属于成员变量不管调用类对象仍是实例对象的isKindOfClass
方法,入口函数统一为 objc_opt_isKindOfClass
找到objc_opt_isKindOfClass
函数函数
BOOL
objc_opt_isKindOfClass(id obj, Class otherClass)
{
#if __OBJC2__
if (slowpath(!obj)) return NO;
Class cls = obj->getIsa();
if (fastpath(!cls->hasCustomCore())) {
for (Class tcls = cls; tcls; tcls = tcls->getSuperclass()) {
if (tcls == otherClass) return YES;
}
return NO;
}
#endif
return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
}
复制代码
isKindOfClass方法的做用:oop
示例:封装isKindOfClass函数post
void isKindOfClassDemo(){
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL re2 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];
NSLog(@"NSObject类对象:%hhd", re1);
NSLog(@"LGPerson类对象:%hhd", re2);
BOOL re3 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL re4 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];
NSLog(@"NSObject实例对象:%hhd", re3);
NSLog(@"LGPerson实例对象:%hhd", re4); }
复制代码
调用isKindOfClassDemo函数优化
isKindOfClassDemo();
-------------------------
NSObject类对象:1
LGPerson类对象:0
NSObject实例对象:1
LGPerson实例对象:1
复制代码
NSObject
的类,获取元类与NSObject
不等,继续寻找获取元类的父类为NSObject
与传入的值相等,返回true。LGPerson
的类,获取元类与LGPerson
不等,继续寻找获取元类的父类为NSObject
的元类,与传入的值依旧不等,继续往上NSObject
元类的父类为NSObject
依旧不等,再往上就是nil
,最后返回falseNSObject
的实例,获取对象的类,与NSObject
相等,返回trueLGPerson
的实例,获取对象的类,与LGPerson
相等,返回true找到isMemberOfClass
方法spa
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
复制代码
封装isMemberOfClass
方法code
void isMemberOfClassDemo(){
BOOL re1 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL re2 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];
NSLog(@"NSObject类对象:%hhd", re1);
NSLog(@"LGPerson类对象:%hhd", re2);
BOOL re3 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL re4 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];
NSLog(@"NSObject实例对象:%hhd", re3);
NSLog(@"LGPerson实例对象:%hhd", re4);
}
复制代码
调用isMemberOfClassDemo
函数
isMemberOfClassDemo();
-------------------------
NSObject类对象:0
LGPerson类对象:0
NSObject实例对象:1
LGPerson实例对象:1
复制代码
NSObject
类调用类方法isMemberOfClass
与NSObject
类比较,很明显,NSObject的元类
与NSObject
自己并不相等,因此返回falseLGPerson
类调用类方法isMemberOfClass
与LGPerson类
比较,LGPerson的元类
与LGPerson
自己并不相等,因此返回falseNSObject
的实例调用实例方法isMemberOfClass
与NSObject
类比较,明显她们是相同的,因此返回trueLGPerson
的实例调用实例方法isMemberOfClass
与LGPerson
类比较,明显的他们是相同的,因此返回true