類也是個對象
➢ 其實類也是一個對象,是Class類型的對象,簡稱“類對象”
➢ Class類型的定義
typedef struct objc_class *Class;
➢ 類名就代表着類對象,每個類只有一個類對象+load和+initialize
➢ +load
在程序啓動的時候會加載所有的類和分類,並調用所有類和分類的+load方法
先加載父類,再加載子類;也就是先調用父類的+load,再調用子類的+load
先加載元原始類,再加載分類
不管程序運行過程有沒有用到這個類,都會調用+load加載
➢ +initialize
在第一次使用某個類時(比如創建對象等),就會調用一次+initialize方法
一個類只會調用一次+initialize方法,先調用父類的,再調用子類的
獲取類對象的2種方式
Class c = [Person class]; // 類方法
或者
Person *p = [Person new];
Class c2 = [p class]; // 對象方法類對象調用類方法
Class c = [Person class];
Person *p2 = [c new];
三、 description方法
1. -description方法
使用NSLog和%@輸出某個對象時,會調用對象的-description方法,並拿到返回值進行輸出
2. + description方法
使用NSLog和%@輸出某個類對象時,會調用類對象+description方法,並拿到返回值進行輸出
3. 修改NSLog的默認輸出
重寫-description或者+description方法即可
4. 死循環陷阱
如果在-description方法中使用NSLog打印self
四、 SEL
1. 方法的存儲位置
➢ 每個類的方法列表都存儲在類對象中
➢ 每個方法都有一個與之對應的SEL類型的對象
➢ 根據一個SEL對象就可以找到方法的地址,進而調用方法
➢ SEL類型的定義
typedef struct objc_selector *SEL;
SEL對象的創建
SEL s = @selector(test);
SEL s2 = NSSelectorFromString(@”test”);SEL對象的其他用法
// 將SEL對象轉爲NSString對象
NSString *str = NSStringFromSelector(@selector(test));
Person *p = [Person new];
// 調用對象p的test方法
[p performSelector:@selector(test)];
五、 NSLog輸出增強
➢ FILE :源代碼文件名
➢ LINE :NSLog代碼在第幾行
➢ _cmd :代表着當前方法的SEL
// 下面的代碼會引發死循環
- (void)test {
[self performSelector:_cmd];
}