1、為什么需要Runtime
- Objective-C 是一門動(dòng)態(tài)語(yǔ)言,它會(huì)將一些工作放在代碼運(yùn)行時(shí)才處理而并非編譯時(shí)。也就是說(shuō),有很多類和成員變量在我們編譯的時(shí)是不知道的,而在運(yùn)行時(shí),我們所編寫的代碼會(huì)轉(zhuǎn)換成完整的確定的代碼運(yùn)行。
- 因此,編譯器是不夠的,我們還需要一個(gè)運(yùn)行時(shí)系統(tǒng)(Runtime system)來(lái)處理編譯后的代碼。
- Runtime 基本是用 C 和匯編寫的,由此可見蘋果為了動(dòng)態(tài)系統(tǒng)的高效而做出的努力。蘋果和 GNU 各自維護(hù)一個(gè)開源的 Runtime 版本,這兩個(gè)版本之間都在努力保持一致。
2、Runtime是什么
*Runtime 又叫運(yùn)行時(shí),是一套底層的 C 語(yǔ)言 API,其為 iOS 內(nèi)部的核心之一,我們平時(shí)編寫的 OC 代碼,底層都是基于它來(lái)實(shí)現(xiàn)的。比如:
[receiver message];
底層運(yùn)行時(shí)會(huì)被編譯器轉(zhuǎn)化為:
objc_msgSend(receiver, selector)
如果其還有參數(shù)比如:
[receiver message:(id)arg...];
底層運(yùn)行時(shí)會(huì)被編譯器轉(zhuǎn)化為:
objc_msgSend(receiver, selector, arg1, arg2, ...)
3、具體應(yīng)用的場(chǎng)景有哪些?
3.1利用關(guān)聯(lián)對(duì)象給分類關(guān)聯(lián)屬性,
//添加關(guān)聯(lián)對(duì)象
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
//獲取關(guān)聯(lián)對(duì)象
id objc_getAssociatedObject(id object, const void * key)
//移除所有關(guān)聯(lián)對(duì)象
void objc_removeAssociatedObjects(id object)
//實(shí)例
@interface NSObject (test)
@property (nonatomic, copy) NSString *name;
@end
.m文件
@implementation NSObject (test)
// 定義關(guān)聯(lián)的key
static const char *key = "name";
-(NSString *)name
{
// 根據(jù)關(guān)聯(lián)的key,獲取關(guān)聯(lián)的值。
return objc_getAssociatedObject(self, key);
}
-(void)setName:(NSString *)name
{
// 第一個(gè)參數(shù):給哪個(gè)對(duì)象添加關(guān)聯(lián)
// 第二個(gè)參數(shù):關(guān)聯(lián)的key,通過這個(gè)key獲取
// 第三個(gè)參數(shù):關(guān)聯(lián)的value
// 第四個(gè)參數(shù):關(guān)聯(lián)的策略
objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
3.2查看私有成員變量
self.textField.placeholder = @"請(qǐng)輸入用戶名"
[self.textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];