Runtime 的应用场景:
关联对象:
(1).仿照 SDWebImage
- <1>给分类动态添加属性;
- <2>解耦;
- <3>简化使用;(2).动态获取类的属性:
- <1>字典 -->模型;
- <2>建立 NSObject 分类;
- <3>1.class_copyPropertyList--> 获取 Person 类.h 文件中的几个属性;
- <4>遍历数组,用的不是 for - in 而是 for 循环 ;
- <5>获得 Person 类. h 文件中的几个属性的名称用 getName方法:property_getName(这里放的是:"属性列表的数组") ;具体代码中会有体现!!!
- <6>与字典转模型过程一样,创建可变数组并把名字添加到这个可变数组中 ;
- <7>释放数组: free(propertyList) ;否则会有内存问题!!!
主 Bundle 栏
ViewController.m 文件
#import "ViewController.h"
#import "Person.h" //继承自NSObject
#import "NSObject+Runtime.h" //NSObject的分类
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//获取 Person 类的属性数组:
NSArray *propertiesArray = [Person MD_objProperties] ;
NSLog(@"%@" , propertiesArray) ;
}
@end
Person.h 文件
#import <Foundation/Foundation.h>
@interface Person : NSObject
/**
* 姓名:
*/
@property (nonatomic, copy) NSString *name ;
/**
* 年龄
*/
@property (nonatomic) NSInteger age ;
/**
* title:
*/
@property (nonatomic, copy) NSString *title ;
/**
* 高度:
*/
@property (nonatomic) double height ;
@end
Person.m 文件
#import "Person.h"
@implementation Person
//什么也没有~空的!!!
@end
NSObject+Runtime.h 文件(给 NSObject 创建的分类)
#import <Foundation/Foundation.h>
@interface NSObject (Runtime)
/**
* 获取累的属性列表数组:
*
* @return 累的属性列表数组
*/
//创建类方法,该类方法返回的数据类型为一个数组:
+ (NSArray *)MD_objProperties ;
@end
NSObject+Runtime.m 文件
#import "NSObject+Runtime.h"
#import <objc/runtime.h>
@implementation NSObject (Runtime)
//该类方法返回的数据类型为包含一个字符串内容为: hello 的数组:
+ (NSArray *)MD_objProperties {
//调用运行时 runtime 取得 Person 类的属性列表:
//Ivar:成员变量:
// class_copyIvarList(__unsafe_unretained Class cls, unsigned int *outCount)
//Method:成员方法:
// class_copyMethodList(__unsafe_unretained Class cls, unsigned int *outCount)
//Property:属性:
// class_copyPropertyList(__unsafe_unretained Class cls, unsigned int *outCount)
//protocol: 协议:
// class_copyProtocolList(__unsafe_unretained Class cls, unsigned int *outCount)
/**
* 参数:
1.__unsafe_unretained Class cls :要获取的类 ;
2.unsigned int *outCount :类属性的个数的指针 ;
*
3.返回值为:所有属性的数组 ;
运行时 Runtime 是 C 语言的概念:
在 C 语言中数组的名字就是指向数组中第一个元素的地址!
*/
//数组的数量:
unsigned int count = 0 ;
objc_property_t *propertyList = class_copyPropertyList([self class], &count) ;
NSLog(@"属性的数量:%@" , [self class]) ;
NSLog(@"属性的数量:%d" , count) ;
//创建可变数组:
NSMutableArray *mArray = [NSMutableArray array] ;
//遍历所有属性:
for (unsigned int i = 0; i < count; i++) {
//1.从数组中取得所有属性:
//注意这里不要再加 * 号,点进会发现他是一个结构体指针!
objc_property_t pty = propertyList[i] ;
//2.获得属性的名称:
//这是一个 C 语言的字符串:
const char *cName = property_getName(pty) ;
// NSLog(@"%s" , cName) ;
//C 语言字符串转成 OC 字符串:
// NSUTF8StringEncoding = 4:
NSString *ocString = [NSString stringWithCString:cName encoding:4] ;
// NSLog(@"%@" , ocString) ;
//将属性名称添加到数组:
[mArray addObject:ocString] ;
}
//一定要释放数组:!!!!!!!!
free(propertyList) ;
return mArray.copy ;
}
@end