一. setValue: forKey: 賦值過程api
1.首先尋找setter方法(兩個)spa
- setName:code
-setIsName:orm
2.而後再尋找成員變量blog
默認 + (BOOL)accessInstanceVariablesDirectly 返回YES;內存
_key > _isKey > key > isKey get
3. 若是以上步驟沒有找到key,則會報異常; 也能夠重寫方法,防止崩潰string
-setValue: forUndefinedKey:it
二. valueForKey: 取值過程io
1.getter方法(三個)
-getKey
-key
-isKey
2.成員變量
_key > _isKey > key > isKey
3.上述沒有,可重寫,防止崩潰
-valueForUndefinedKey
三. runtime 簡單實現 KVC
新建一個NSObject 一個分類
1 #import "NSObject+kvc.h" 2 #import <objc/runtime.h> 3 @implementation NSObject (kvc) 4 - (void)xs_setValue:(id)value forKey:(NSString *)key{ 5 //key 須要合法 6 if (key == nil || key.length == 0) { 7 return; 8 } 9 //一.setter 方法 10 //調用相關setter方法(capitalizedString 首字母大寫) 11 NSString *setKey = [NSString stringWithFormat:@"set%@:",[key capitalizedString]]; 12 //調用 13 if ([self respondsToSelector:NSSelectorFromString(setKey)]) { 14 [self performSelector:NSSelectorFromString(setKey) withObject:value]; 15 return; 16 } 17 NSString *setIsKey = [NSString stringWithFormat:@"setIs%@:",[key capitalizedString]]; 18 if ([self respondsToSelector:NSSelectorFromString(setIsKey)]) { 19 [self performSelector:NSSelectorFromString(setIsKey) withObject:value]; 20 return; 21 } 22 23 //異常處理方法 24 if (![self.class accessInstanceVariablesDirectly]) { 25 NSException *exception = [NSException exceptionWithName:@"XSKVC Exception" reason:@"你返回了NO啊!" userInfo:nil]; 26 @throw exception; 27 return; 28 } 29 //二.成員變量 30 unsigned int count = 0; 31 //獲取全部成員變量 32 Ivar *ivars = class_copyIvarList([self class], &count);//解釋:在C中,copy new create 在堆區開闢內存空間 33 // NSMutableArray *array = [NSMutableArray array]; 34 // for (int i = 0; i<count; i++) { 35 // Ivar ivar = ivars[i]; 36 // const char *name = ivar_getName(ivar); 37 // NSString *keyName = [NSString stringWithUTF8String:name]; 38 // [array addObject:keyName]; 39 // } 40 //_key (按照優先級:_key > _isKey > key > isKey) 41 for (int i = 0; i<count; i++) { 42 Ivar ivar = ivars[i]; 43 NSString *keyName = [NSString stringWithUTF8String:ivar_getName(ivar)]; 44 if ([keyName isEqualToString:[NSString stringWithFormat:@"_%@",key]]) { 45 object_setIvar(self, ivar, value); 46 free(ivars); 47 return; 48 } 49 } 50 //_isKey 51 for (int i = 0; i<count; i++) { 52 Ivar ivar = ivars[i]; 53 NSString *keyName = [NSString stringWithUTF8String:ivar_getName(ivar)]; 54 if ([keyName isEqualToString:[NSString stringWithFormat:@"_is%@",key.capitalizedString]]) { 55 object_setIvar(self, ivar, value); 56 free(ivars); 57 return; 58 } 59 } 60 //key 61 for (int i = 0; i<count; i++) { 62 Ivar ivar = ivars[i]; 63 NSString *keyName = [NSString stringWithUTF8String:ivar_getName(ivar)]; 64 if ([keyName isEqualToString:[NSString stringWithFormat:@"%@",key]]) { 65 object_setIvar(self, ivar, value); 66 free(ivars); 67 return; 68 } 69 } 70 //isKey 71 for (int i = 0; i<count; i++) { 72 Ivar ivar = ivars[i]; 73 NSString *keyName = [NSString stringWithUTF8String:ivar_getName(ivar)]; 74 if ([keyName isEqualToString:[NSString stringWithFormat:@"is%@",key.capitalizedString]]) { 75 object_setIvar(self, ivar, value); 76 free(ivars); 77 return; 78 } 79 } 80 81 //處理異常 82 [self setValue:value forUndefinedKey:key]; 83 free(ivars); 84 85 }