說到Objc運行時,若是你還不清楚,那可要看仔細了,若是你是靠顏值而不是才華可以順利經過面試,喵了個咪的,我也想去試試html
iOS出現時就是運行時2.0版本了,和舊的相比擁有兩大特性:
第一,就是修改,增長或刪除一個類的實例變量,不用再從新編譯子類就能夠用了。
第二,就是加爲@property加入了Synthesizeios
請將屬性property(atomic,nonatomic, assign, weak, strong, copy, readonly, readwrite blah!blah!)按照功能分組git
請回答下列@property變量cool和cat的默認屬性github
@interface ViewController : UIViewController @property BOOL cool; @property NSObject *cat; @end
Objc運行時至關於Objective-C的操做系統,當咱們編譯代碼時,編譯器把源碼編譯成運行時可以懂得數據結構(好比isa包括類的繼承信息)和運行時方法(好比objc_msgSend), 剩下的就交給運行時動態處理了。面試
@interface NSObject{ objc_class *isa } //點開isa連接搜索struct objc_class : objc_object可以查到其聲明 struct objc_class : objc_object { // Class ISA; objc_class *superclass; .... 方法派遣表 selector對應的C語言函數 .... } 從objc_class聲明能夠看出,每個isa->superclass一樣是objc_class類型, 這樣就組成了一個繼承的鏈表結構
1.寫Objective-C代碼必然用到,雖然沒這種感受
2.調用NSObject運行時方法
3.直接調用運行時API緩存
objc方法只不過是C語言方方法,加上兩個特殊的參數第一個是receiver(self),第二個參數是selector(_cmd)數據結構
好比如下的方法調用 [receiver message:arg1] //假設定義arg1爲BOOL類型
具體實現: (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(message:)];
運行時:app
`objc_msgSend(receiver, selector, arg1)`
objc_msgSend作的事情以下:ide
根據receiver和selector先在receiver的方法派遣表裏面查找是否有selector這個方法實現, 若是沒找到,receiver->isa->superclass去查找,以此類推,直到找到對應的方法實現,若直到NSObject都沒有找到對應實現,中間過程在下文解釋,最後掉用[receiver doesNotRecognizeSelector:_cmd]
就拋異常出錯了函數
將全部參數傳給具體實現方法調用
將具體實現結果反回來
儘管objc_msgSend在成功調用一次方法以後,每一個Class會有緩存,下次重複調用該方法時,查找速度會大大提升,可是仍是有運行時消息發送的時間,若是一個函數被調用成千上萬次,爲了減小消息派遣時間,能夠跳過運行時objc_msgSend,直接調用方法實現
void (*message)(id, SEL, BOOL); int i; message = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(message:)]; for ( i = 0 ; i < 1000 ; i++ ) setter(targetList[i], @selector(message:), YES);
原子性:atomic,nonatomic
讀寫性: readwrite, readonly
ARC版內存管理: assign, strong, copy, weak
@property cool = TB,V_cool @property cat = T@"NSObject",&,V_cat
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. id LenderClass = objc_getClass("ViewController"); unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; fprintf(stdout, "@property %s = %s\n", property_getName(property), property_getAttributes(property)); } }
子問題2: 如何解讀?首先說明這奇怪的字符時編譯器乾的好事啦,參考主要是這裏還有這裏
The string returned by |property_getAttributes| starts with a T followed by the @encode type and a comma, and finishes with a V followed by the name of the backing instance variable.
上面一坨就是說,property_getAttributes得到的字符串的格式,以T開頭,而後是<變量類型>,而後是一個逗號,而後是<屬性>,最後是一個V,再日後就是下劃線_和變量名了
/*根據文檔: 若是是readonly應該有R屬性, 因此默認應該是readwrite 若是是weak,strong,copy應該分別有W, &, C, 因此默認應該是assign 若果有nonatomic應該有N, 因此默認是atomic TB,V_cool B表明BOOL, 中間什麼屬性都沒有對不對,根據以上分析,默認是atomic, assign, readwrite T@"NSObject",&,V_cat 則是atomic, strong, readwrite */