class_copyPropertyList
- 看到名字可以看出來他是來獲取屬性的
- 只能獲取到 @property 聲明的屬性
class_copyIvarList
- 用來獲取所有的變量的
- 獲取所有的變量,當然包括因 @property 修飾而自動產生的變量 _name
總結
- class_copyPropertyList 只能獲取到 @property 聲明的屬性
- class_copyIvarList 用來獲取所有的變量的
- 但是以上兩個方法都只能獲取到當前類的屬性和變量(也就是說獲取不到父類的屬性和變量)
驗證
以上的結論通過一段代碼可以驗證
首先聲明類:
@interface KK : NSObject { int _i; } @property NSString * name; @property NSString * family; @end @implementation KK - (NSString *)description { return [NSString stringWithFormat:@"KK -> description: name: %@", self.name]; } @end @interface MM : KK @property int age; @end @implementation MM @end
第一段代碼:
KK * k = [[KK alloc] init]; unsigned int a; objc_property_t * result = class_copyPropertyList(object_getClass(k), &a); for (unsigned int i = 0; i < a; i++) { objc_property_t o_t = result[i]; NSLog(@"%@", [NSString stringWithFormat:@"%s", property_getName(o_t)]); } free(result); Ivar * iv = class_copyIvarList(object_getClass(k), &a); for (unsigned int i = 0; i < a; i++) { Ivar i_v = iv[i]; NSLog(@"%@", [NSString stringWithFormat:@"%s", ivar_getName(i_v)]); } free(iv);
2018-06-07 14:19:25.184787+0800 runtime[16059:422758] name 2018-06-07 14:19:25.184884+0800 runtime[16059:422758] family 2018-06-07 14:19:25.184940+0800 runtime[16059:422758] _i 2018-06-07 14:19:25.184960+0800 runtime[16059:422758] _name 2018-06-07 14:19:25.184977+0800 runtime[16059:422758] _family
如上可以驗證
- class_copyPropertyList 只能獲取 @property 修飾的屬性
第二段代碼
KK * k = [[MM alloc] init]; unsigned int a; objc_property_t * result = class_copyPropertyList(object_getClass(k), &a); for (unsigned int i = 0; i < a; i++) { objc_property_t o_t = result[i]; NSLog(@"%@", [NSString stringWithFormat:@"%s", property_getName(o_t)]); } free(result); Ivar * iv = class_copyIvarList(object_getClass(k), &a); for (unsigned int i = 0; i < a; i++) { Ivar i_v = iv[i]; NSLog(@"%@", [NSString stringWithFormat:@"%s", ivar_getName(i_v)]); } free(iv);
2018-06-07 14:21:26.258232+0800 runtime[16089:423658] age 2018-06-07 14:21:26.258295+0800 runtime[16089:423658] _age
- 只獲取當前類的屬性和方法
獲取指定類的屬性以及父類的所有屬性
/** 獲取指定類的屬性 @param cls 被獲取屬性的類 @return 屬性名稱 [NSString *] */ NSArray * getClassProperty(Class cls) { if (!cls) return @[]; NSMutableArray * all_p = [NSMutableArray array]; unsigned int a; objc_property_t * result = class_copyPropertyList(cls, &a); for (unsigned int i = 0; i < a; i++) { objc_property_t o_t = result[i]; [all_p addObject:[NSString stringWithFormat:@"%s", property_getName(o_t)]]; } free(result); return [all_p copy]; } /** 獲取指定類(以及其父類)的所有屬性 @param cls 被獲取屬性的類 @param until_class 當查找到此類時會停止查找,當設置爲 nil 時,默認採用 [NSObject class] @return 屬性名稱 [NSString *] */ NSArray * getAllProperty(Class cls, Class until_class) { Class stop_class = until_class ?: [NSObject class]; if (class_getSuperclass(cls) == stop_class) return @[]; NSMutableArray * all_p = [NSMutableArray array]; [all_p addObjectsFromArray:getClassProperty(cls)]; if (class_getSuperclass(cls) == stop_class) { return [all_p copy]; } else { [all_p addObjectsFromArray:getAllProperty([cls superclass], stop_class)]; } return [all_p copy]; }
獲取指定類以及其父類所有的變量
/** 獲取指定類的變量 @param cls 被獲取變量的類 @return 變量名稱集合 [NSString *] */ NSArray * getClassIvar(Class cls) { if (!cls) return @[]; NSMutableArray * all_p = [NSMutableArray array]; unsigned int a; Ivar * iv = class_copyIvarList(cls, &a); for (unsigned int i = 0; i < a; i++) { Ivar i_v = iv[i]; [all_p addObject:[NSString stringWithFormat:@"%s", ivar_getName(i_v)]]; } free(iv); return [all_p copy]; } /** 獲取指定類(以及其父類)的所有變量 @param cls 被獲取變量的類 @param until_class 當查找到此類時會停止查找,當設置爲 nil 時,默認採用 [NSObject class] @return 變量名稱集合 [NSString *] */ NSArray * getAllIvar(Class cls, Class until_class) { Class stop_class = until_class ?: [NSObject class]; if (class_getSuperclass(cls) == stop_class) return @[]; NSMutableArray * all_p = [NSMutableArray array]; [all_p addObjectsFromArray:getClassIvar(cls)]; if (class_getSuperclass(cls) == stop_class) { return [all_p copy]; } else { [all_p addObjectsFromArray:getAllIvar([cls superclass], stop_class)]; } return [all_p copy]; }