1.归档解档
- (id)initWithCoder:(NSCoder *)decoder {
if (self == [super init]) {
unsigned int count;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i=0; i<count; i++) {
Ivar ivar = ivars[i];
NSString *ivarName = [NSString stringWithFormat:@"%s", ivar_getName(ivar)];
if ([ivarName hasPrefix:@"_"]){
ivarName = [ivarName stringByReplacingOccurrencesOfString:@"_" withString:@""];
}
[self setValue:[decoder decodeObjectForKey:ivarName] forKey:ivarName];
}
free(ivars);
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
unsigned int count;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i=0; i<count; i++) {
Ivar ivar = ivars[i];
NSString *ivarName = [NSString stringWithFormat:@"%s", ivar_getName(ivar)];
if ([ivarName hasPrefix:@"_"]){
ivarName = [ivarName stringByReplacingOccurrencesOfString:@"_" withString:@""];
}
[coder encodeObject:[self valueForKey:ivarName] forKey:ivarName];
}
free(ivars);
}
使用起来,可以定义为宏命令。以后需要归解档的模型只需要在遵守NSCoding协议后,再在.m里加上NSCodingEmplementation即可。
#define NSCodingEmplementation - (id)initWithCoder:(NSCoder *)decoder {\
if (self == [super init]) {\
unsigned int count;\
Ivar *ivars = class_copyIvarList([self class], &count);\
for (int i=0; i<count; i++) {\
Ivar ivar = ivars[i];\
NSString *ivarName = [NSString stringWithFormat:@"%s", ivar_getName(ivar)];\
if ([ivarName hasPrefix:@"_"]){\
ivarName = [ivarName stringByReplacingOccurrencesOfString:@"_" withString:@""];\
}\
[self setValue:[decoder decodeObjectForKey:ivarName] forKey:ivarName];\
}\
free(ivars);\
}\
return self;\
}\
- (void)encodeWithCoder:(NSCoder *)coder {\
unsigned int count;\
Ivar *ivars = class_copyIvarList([self class], &count);\
for (int i=0; i<count; i++) {\
Ivar ivar = ivars[i];\
NSString *ivarName = [NSString stringWithFormat:@"%s", ivar_getName(ivar)];\
if ([ivarName hasPrefix:@"_"]){\
ivarName = [ivarName stringByReplacingOccurrencesOfString:@"_" withString:@""];\
}\
[coder encodeObject:[self valueForKey:ivarName] forKey:ivarName];\
}\
free(ivars);\
}
测试一下
#import <Foundation/Foundation.h>
@interface Student : NSObject<NSCoding>
{
@public
NSUInteger _classId;
NSString *_address;
}
@property(nonatomic, assign) NSUInteger studentId;
@property(nonatomic, copy) NSString *name;
@property(nonatomic, assign) int age;
@property(nonatomic, copy) NSString *phoneNo;
@end
#import "Student.h"
@implementation Student
NSCodingEmplementation
@end
Student *stu = [Student new];
stu.studentId = 1;
stu.name = @"hello-world";
stu.age = 39;
stu.phoneNo = @"18712346789";
stu->_address = @"China HongKong";
stu->_classId = 12;
NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
NSString *dataPath = [cachePath stringByAppendingPathComponent:@"student.data"];
BOOL success = [NSKeyedArchiver archiveRootObject:stu toFile:dataPath];
if (!success) {
NSLog(@"NSKeyedArchiver failure");
}
Student *archiveStu = [NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithContentsOfFile:dataPath]];
NSLog(@"archiveDic.keyvalues = %@", archiveStu.keyvalues);
结果OK
archiveDic.keyvalues = {
address = "China HongKong";
age = 39;
classId = 12;
name = "hello-world";
phoneNo = 18712346789;
studentId = 1;
}
2.字典,模型互转
#import <Foundation/Foundation.h>
@interface NSObject (JSONModel)
+ (id)modelWithKeyValues:(NSDictionary *)dic;
- (NSDictionary *)keyValues;
@end
#import "NSObject+JSONModel.h"
#import <objc/runtime.h>
@implementation NSObject (JSONModel)
+ (id)modelWithKeyValues:(NSDictionary *)dic {
Class cls = objc_getClass(NSStringFromClass([self class]).UTF8String);
id obj = [[cls alloc]init];
unsigned int count, i;
Ivar *ivars = class_copyIvarList([self class], &count);
for (i=0; i<count; i++) {
Ivar ivar = ivars[i];
NSString *ivarName = [NSString stringWithFormat:@"%s", ivar_getName(ivar)];
if ([ivarName hasPrefix:@"_"])
ivarName = [ivarName stringByReplacingOccurrencesOfString:@"_" withString:@""];
if (dic[ivarName])
[obj setValue:dic[ivarName] forKey:ivarName];
}
return obj;
}
- (NSDictionary *)keyValues {
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:0];
unsigned int count ,i;
Ivar *ivars = class_copyIvarList([self class], &count);
for(i=0; i<count; i++) {
Ivar ivar = ivars[i];
NSString *ivarName = [NSString stringWithFormat:@"%s", ivar_getName(ivar)];
if ([ivarName hasPrefix:@"_"]) {
ivarName = [ivarName stringByReplacingOccurrencesOfString:@"_" withString:@""];
}
dic[ivarName] = [self valueForKey:ivarName];
}
return dic;
}
@end
测试一下
Student *stu = [Student new];
stu.studentId = 1;
stu.name = @"hello-world";
stu.age = 29;
stu.phoneNo = @"18712346789";
stu->_address = @"China HongKong";
stu->_classId = 12;
NSDictionary *keyvalues = stu.keyvalues;
NSLog(@"keyvalues = %@",keyvalues);
Student *newStu = [Student modelWithKeyValues:keyvalues];
NSLog(@"newStu.keyvalues = %@", newStu.keyvalues);
结果OK
keyvalues = {
address = "China HongKong";
age = 39;
classId = 12;
name = "hello-world";
phoneNo = 18712346789;
studentId = 1;
}
newStu.keyvalues = {
address = "China HongKong";
age = 39;
classId = 12;
name = "hello-world";
phoneNo = 18712346789;
studentId = 1;
}
3.分类中添加属性
@interface Student(Family)
@property (nonatomic, copy) NSString *firstName;
@end
@implementation Student(Family)
- (void)setFirstName:(NSString *)firstName {
objc_setAssociatedObject(self, @selector(firstName), firstName, OBJC_ASSOCIATION_RETAIN);
}
- (NSString *)firstName {
return objc_getAssociatedObject(self, _cmd);
}
@end
测试一下
Student *stu = [Student new];
stu.firstName = @"wang";
NSLog(@"stu.firstName = %@",stu.firstName);
结果OK
stu.firstName = wang
网友评论