類的本質
-
本質
- 類其實也是一個 對象, 這個對象會在這個類第一次被使用的時候創建, 一個類再內存中只有一份類對象
- 只要有了類對象, 將來就可以通過類對象來創建實例對象
- 實例對象中有一個
isa指針
, 指向創建自己的類對象 - 類對象中保存了當前對象所有的對象方法, 當給一個實例對象發送消息的時候, 會根據實例對象中的isa指針去對應的類對象中查找
- 如何獲取類對象: [實例對象 class]/ [類名 class];
-
類對象的應用場景:
- 1用于創建實例對象
- 2用于調用類方法
類的啟動過程
-
load
方法:- 只要程序啟動就會將所有類的代碼加載到內存中, 放到代碼區
-
load
方法會在當前類被 加載到內存 的時候調用, 有且僅會 調用一次 - 如果存在繼承關系, 會 先調用父類的load方法, 再調用子類的load方法
-
initialize
方法:- 當前類第一次被使用的時候就會調用(創建類對象的時候)
-
initialize
方法在整個程序的運行過程中只會被 調用一次, 無論使用多少次這個類都只會調用一次 -
initialize
用于對某一個類進行 一次性的初始化 -
initialize
和load
一樣, 如果存在繼承關系, 會 先調用父類的initialize, 再調用子類的initialize
SEL類型
三種用法
- 配合對象/類來 檢查 對象/類中有沒有實現某一個方法
SEL sel = @selector(setAge:);
Person *p = [Person new];
// 判斷p對象中有沒有實現-號開頭的setAge:方法
// 如果P對象實現了setAge:方法那么就會返回YES
// 如果P對象沒有實現setAge:方法那么就會返回NO
BOOL flag = [p respondsToSelector:sel];
NSLog(@"flag = %i", flag);
- 2.配合對象/類來 調用某一個SEL方法
SEL sel = @selector(demo);
Person *p = [Person new];
// 調用p對象中sel類型對應的方法
[p performSelector:sel];
SEL sel1 = @selector(signalWithNumber:);
// withObject: 需要傳遞的參數
// 注意: 如果通過performSelector調用有參數的方法, 那么參數必須是對象類型,
// 也就是說方法的形參必須接受的是一個對象, 因為withObject只能傳遞一個對象
[p performSelector:sel1 withObject:@"13838383438"];
SEL sel2 = @selector(setAge:);
[p performSelector:sel2 withObject:@(5)];
NSLog(@"age = %i", p.age);
// 注意:performSelector最多只能傳遞2個參數
SEL sel3 = @selector(sendMessageWithNumber:andContent:);
[p performSelector:sel3 withObject:@"138383438" withObject:@"abcdefg"];
- 3.配合對象 將SEL類型作為方法的形參
Car *c = [Car new];
SEL sel = @selector(run);
Person *p = [Person new];
[p makeObject:c andSel:sel];// 調用傳入對象的指定方法, 此處是c的run方法