一、概述
修改私有屬性,是我們?nèi)粘i_發(fā)中常見(jiàn)的一個(gè)場(chǎng)景。比如修改三方庫(kù)的某個(gè)屬性,可三方庫(kù)并沒(méi)有暴露該屬性在頭文件??偟膩?lái)說(shuō),修改私有屬性,兩種方案:KVC和Runtime。今天這里不介紹原理,只講實(shí)操。
總體思路:通過(guò)繼承要修改類,拿到要修改的屬性或者成員變量,改變其值,再賦值給該類。
二、KVC
以下舉例,通過(guò)子類ZXSonViewController繼承父類ZXParentViewController和,在viewDidLoad方法里做演示。
I、屬性類型-系統(tǒng)類
父類定義了私有屬性name
image.png
子類繼承父類,通過(guò)KVC修改
image.png
打印結(jié)果:
image.png
II、屬性類型-自定義類
此時(shí)使用的Api由[setValue: forKey:]換為[setValue:forKeyPath:]
父類使用自定義類一個(gè)作為屬性
image.png
子類通過(guò)[setValue:forKeyPath:] 修改
image.png
看下打印結(jié)果
image.png
III、成員變量-非枚舉
當(dāng)修改的是成員變量時(shí)
image.png
子類
image.png
打印結(jié)果
image.png
IV、成員變量-枚舉
由于struct本身并不遵循KVC協(xié)議,但是我們可以轉(zhuǎn)化為NSValue解決
父類使用一個(gè)枚舉做成員變量
image.png
子類通過(guò)五步操作,修改父類成員變量值
- (void)viewDidLoad {
[super viewDidLoad];
/**當(dāng)修改私有變量時(shí)枚舉時(shí),由以下五步*/
//1、通過(guò)KVC獲取父類父類成員變量,賦值給NSValue
NSValue* result = [self valueForKey:@"location"];
//2、將NSValue轉(zhuǎn)化為結(jié)構(gòu)一樣,但名字不一樣的新結(jié)構(gòu)體
struct ZXSonLocation sonLocation;
[result getValue:&sonLocation];
//3、修改目標(biāo)字段
sonLocation.x = 999.0;
//4、將新的結(jié)構(gòu)體再轉(zhuǎn)為NSValue
NSValue* newValue = [NSValue valueWithBytes:&sonLocation objCType:@encode(struct ZXSonLocation)];
//5、通過(guò)KVC賦值給父類
[self setValue:newValue forKey:@"location"];
}
截圖如下
image.png
看下打印結(jié)果
image.png
三、總結(jié)
通過(guò)KVC修改私有屬性或者成員變量的方法基本都列舉完了,但注意KVC本身屬于硬編碼形式,容易操作閃退,使用時(shí)要做好安全防護(hù)。