這是我參與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