ios OC 獲取所有屬性、變量 class_getProperty class_copyPropertyList class_copyIvarList

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];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章