1.归档中用到的Runtime,类的属性较多的时候用着比较方便,不用写那么多代码
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface Person : NSObject<NSCoding> @property (nonatomic ,assign)CGFloat height; @property (nonatomic, copy) NSString *name; @property (nonatomic, strong) NSNumber *age; @property (nonatomic, assign) int no; @end 123456789 123456789 #import "Person.h" #import <objc/message.h> #import <objc/runtime.h> @implementation Person -(void)encodeWithCoder:(NSCoder *)encoder { unsigned int count = 0; Ivar *ivars = class_copyIvarList([Person class], &count); for (int i = 0; i<count; i++) { // 取出i位置对应的成员变量 Ivar ivar = ivars[i]; // 查看成员变量 const char *name = ivar_getName(ivar); // 归档 NSString *key = [NSString stringWithUTF8String:name]; id value = [self valueForKey:key]; [encoder encodeObject:value forKey:key]; } } -(instancetype)initWithCoder:(NSCoder *)decoder { if (self = [super init]) { unsigned int count = 0; Ivar *ivars = class_copyIvarList([Person class], &count); for (int i = 0; i<count; i++) { // 取出i位置对应的成员变量 Ivar ivar = ivars[i]; // 查看成员变量 const char *name = ivar_getName(ivar); // 归档 NSString *key = [NSString stringWithUTF8String:name]; id value = [decoder decodeObjectForKey:key]; // 设置到成员变量身上 [self setValue:value forKey:key]; } } return self; } @end 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152存储文件
//1.创建对象 Person *p=[[Person alloc]init]; p.name=@"??????"; p.age=@23; p.height = 1.7; //2.获取文件路径 NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; NSString *path=[docPath stringByAppendingPathComponent:@"person"]; NSLog(@"path=%@",path); //3.将自定义的对象保存到文件中 [NSKeyedArchiver archiveRootObject:p toFile:path]; 1234567891011 1234567891011读取文件
//1.获取文件路径 NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; NSString *path=[docPath stringByAppendingPathComponent:@"person"]; NSLog(@"path=%@",path); //2.从文件中读取对象 Person *p=[NSKeyedUnarchiver unarchiveObjectWithFile:path]; 1234567 12345672.KVC与归档其实用到Runtime的方法是一样的 两者都是用 Ivar *ivars = class_copyIvarList([Person class], &count);的方法,获取成员变量, 但是还是不建议使用Runtime 获取成员变量 然后在setValue影响性能.
3.分类添加属性 Category
用于给class及其subclass添加新的方法
有自己单独的 .h 和 .m 文件
用于添加新方法,而不能添加新属性(property)
可以用Runtime动态添加属性,下面两种形式都可以为person 添加属性
#import "Person.h" @interface Person (sex) @property (nonatomic, strong) NSString *property; @property (nonatomic, copy) NSString *str; - (void)nishi; @end 12345678 12345678 #import "Person+sex.h" #import <objc/runtime.h> static char strKey; @implementation Person (sex) - (NSObject *)property { return objc_getAssociatedObject(self, @selector(property)); } - (void)setProperty:(NSString *)property { objc_setAssociatedObject(self, @selector(property), property, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -(void)setStr:(NSString *)str { objc_setAssociatedObject(self, &strKey, str, OBJC_ASSOCIATION_COPY); } -(NSString *)str { return objc_getAssociatedObject(self, &strKey); } - (void)nishi{ } @end 123456789101112131415161718192021222324252627 123456789101112131415161718192021222324252627注意:(不知道为什么在分类中添加的方法,打印的时候的确是看到添加进去了,但是在用
Ivar *vars = class_copyIvarList([p class], &outCount); 1 1获取成员变量列表的时候,获取不到增加的使用,所以这两种方法在同时使用的时候要注意,但是添加的方法可以打印出来);
unsigned int outCount = 0; Ivar *vars = class_copyIvarList([p class], &outCount); // 遍历所有的成员变量 for (int i = 0; i < outCount; i++) { Ivar ivar = vars[i]; // 取出第i个位置的成员变量 const char *propertyName = ivar_getName(ivar); // 获取变量名 const char *propertyType = ivar_getTypeEncoding(ivar); // 获取变量编码类型 printf("---%s--%s\n", propertyName, propertyType); } unsigned int numIvars = 0; Method *meth = class_copyMethodList([Person class], &numIvars); for(int i = 0; i < numIvars; i++) { Method thisIvar = meth[i]; SEL sel = method_getName(thisIvar); const char *name = sel_getName(sel); NSLog(@"zp method :%s", name); }