1.可以通過Runtime來遍歷某一個類的所有成員變量和私有屬性,然后可以通過KVC進行自己想要的相關操作
例如 現(xiàn)在想要修改textField在開始編輯時的placeholder文字顏色發(fā)生改變,就可以使用這個方法,拿到textField這個類的私有屬性"_placeholderLabel",然后通過KVC進行修改即可,代碼如下
```
//用來記錄屬性的數(shù)量
unsigned int count = 0;
//賦值類中的所有實例對象的屬性
//返回值是一個屬性列表,可以通過Ivar類型的指針來訪問
Ivar *ivar =? class_copyIvarList([UITextField class], &count);
//利用運行時找出textField的_placeholderLabel屬性,然后用KVC進行賦值
for (unsigned int i = 0; i < count; i++) {
//ivar_getName獲得該指針指向的屬性的名稱
const char *name = ivar_getName(*(ivar + i));
NSLog(@"%s",name);
}
//copy以后內(nèi)存要釋放
free(ivar);
```
2.如果在做數(shù)據(jù)持久化的歸檔解檔的時候,如果一個界面對應的模型所存的屬性很多,那么我們是不是要在以下的方法中寫若干個"encode"和encode方法
```
- (void)encodeWithCoder:(NSCoder *)aCoder;
{
//這里省略若干個
[aCoder encodeObject:value forKey:key];
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
//這里省略若干個
self.property = [aDecoder decodeObjectForKey:key];
}
然后用了RunTime以后的代碼無論有多少個屬性,都可以是這樣的
```
- (void)encodeWithCoder:(NSCoder *)aCoder{
unsigned int outCount = 0;
Ivar *vars = class_copyIvarList([self class], &outCount);
for (int i = 0; i < outCount; i ++) {
Ivar var = vars[i];
const char *name = ivar_getName(var);
NSString *key = [NSString stringWithUTF8String:name];
id value = [self valueForKey:key];
[aCoder encodeObject:value forKey:key];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
unsigned int outCount = 0;
Ivar *vars = class_copyIvarList([self class], &outCount);
for (int i = 0; i < outCount; i ++) {
Ivar var = vars[i];
const char *name = ivar_getName(var);
NSString *key = [NSString stringWithUTF8String:name];
id value = [aDecoder decodeObjectForKey:key];
[self setValue:value forKey:key];
}
}
return self;
}
```
3.關于category中為什么不能添加成員變量的問題,在RunTime簡介中,說到Class的時候有了說明
class的定義如下
typedef struct objc_class *Class;
```
objc_class 結構體是醬紫的
```
struct objc_class {
Class isa? OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
const char *name? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
long version? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
long info? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
long instance_size? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
struct objc_cache *cache? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
```
category的原理就是利用class中的"methodLists"動態(tài)的添加方法,但是并不能利用常規(guī)的方法添加屬性
但是可以利用RunTime來動態(tài)地給一個類添加屬性
```
//setter方法
objc_setAssociatedObject(self,@"name",name,OBJC_ASSOCIATION_COPY_NONATOMIC);
//getter方法
return objc_getAssociatedObject(self,@"name");
```
大概我用到的暫時就這么多,希望能對大家有所幫助
胥鴻儒