[super encodeWithCoder:aCoder];
NSDictionary *pros = [self properties_aps];
for(NSString *key in [pros allKeys]) {
if ([key isEqualToString:@"appInfo"]) {
NSData *appData = [NSKeyedArchiver archivedDataWithRootObject:[pros objectForKey:key]];
[aCoder encodeObject:appData forKey:key];
continue;
}
[aCoder encodeObject:[pros objectForKey:key] forKey:key];
}
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
NSArray *arr = [self getAllProperties];
for(NSString *key in arr) {
if ([key isEqualToString:@"appInfo"]) {
id value = [aDecoder decodeObjectForKey:key];
_appInfo = [NSKeyedUnarchiver unarchiveObjectWithData:value];
continue;
}
id value = [aDecoder decodeObjectForKey:key];
if (value)
[self setValue:value forKey:key];
}
}
return self;
}
- (id)copyWithZone:(NSZone *)zone{
appRecord *copy=[[[self class] allocWithZone:zone]init];
[copy setAppID:self.appID];
[copy setAppName:self.appName];
[copy setAppVersion:self.appVersion];
[copy setAppSize:self.appSize];
return copy;
}
//NSObject+Runtime.h 类的.h .m 文件
#import <Foundation/Foundation.h>
@interface NSObject(Runtime)
- (NSDictionary *)properties_aps;
- (NSArray *)getAllProperties;
- (NSDictionary *)getAllPropertiesAndType;
- (void)getMothList;
- (void)getAllVars;
@end
#import <objc/runtime.h>
#import "NSObject+Runtime.h"
@implementation NSObject(Runtime)
/* 获取对象的所有属性 以及属性值 [所有声明在.h和.m文件中的property都可获取]*/
- (NSDictionary *)properties_aps
{
NSMutableDictionary *props = [NSMutableDictionary dictionary];
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for (i = 0; i<outCount; i++)
{
objc_property_t property = properties[i];
const char* char_f =property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:char_f];
id propertyValue = [self valueForKey:(NSString *)propertyName];//获取出的值不用管是对象还是基础数据类型,一律为对象型
if (propertyValue) [props setObject:propertyValue forKey:propertyName];
}
free(properties);
return props;
}
/* 获取对象的所有属性,不包括属性值 [所有声明在.h和.m文件中的property都可获取]*/
- (NSArray *)getAllProperties
{
u_int count;
objc_property_t *properties =class_copyPropertyList([self class], &count);
NSMutableArray *propertiesArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i<count; i++)
{
const char* propertyName =property_getName(properties[i]);
[propertiesArray addObject: [NSString stringWithUTF8String: propertyName]];
}
free(properties);
return propertiesArray;
}
/* 获取对象的所有属性及属性的类型,不包括属性值 [所有声明在.h和.m文件中的property都可获取]*/
- (NSDictionary *)getAllPropertiesAndType
{
u_int count;
objc_property_t *properties =class_copyPropertyList([self class], &count);
NSMutableDictionary *propertiesDic = [NSMutableDictionary dictionaryWithCapacity:count];
for (int i = 0; i<count; i++)
{
const char* propertyName =property_getName(properties[i]);
const char* propertyType =property_getAttributes(properties[i]);
[propertiesDic setObject:[NSString stringWithUTF8String: propertyType] forKey:[NSString stringWithUTF8String: propertyName]];
}
free(properties);
return propertiesDic;
}
/* 获取对象的所有方法 */
-(void)getMothList
{
unsigned int mothCout_f =0;
Method* mothList_f = class_copyMethodList([self class],&mothCout_f);
for(int i=0;i<mothCout_f;i++)
{
Method temp_f = mothList_f[i];
//IMP imp_f = method_getImplementation(temp_f);
//SEL name_f = method_getName(temp_f);
const char* name_s =sel_getName(method_getName(temp_f));
int arguments = method_getNumberOfArguments(temp_f);
const char* encoding =method_getTypeEncoding(temp_f);
NSLog(@"方法名:%@,参数个数:%d,编码方式:%@",[NSString stringWithUTF8String:name_s],
arguments,[NSString stringWithUTF8String:encoding]);
}
free(mothList_f);
}
/*获取对象所有的成员变量,属性的成员变量标示就多一下划线 [所有声明在.h和.m文件中的property都可获取]*/
- (void)getAllVars {
unsigned int numIvars; //成员变量个数
Ivar *vars = class_copyIvarList([self class], &numIvars);
NSString *key=nil;
for(int i = 0; i < numIvars; i++) {
Ivar thisIvar = vars[i];
key = [NSString stringWithUTF8String:ivar_getName(thisIvar)]; //获取成员变量的名字
NSLog(@"variable name :%@", key);
key = [NSString stringWithUTF8String:ivar_getTypeEncoding(thisIvar)]; //获取成员变量的数据类型
NSLog(@"variable type :%@", key);
}
free(vars);
}
@end
NSKeyedUnarchiver
NSKeyedArchiver
Archive实现了三个委托方法1)encodeWithCoder: 2)initWithCoder: 3)copyWithZone:
1)encodeWithCoder
Encodes the receiverusing a given archiver
通过一个给定的archiver把消息接收者进行编码。
当接收到encodeObject消息的时候,类终端encodeWithCoder方法被调用。
2)initWithCoder
Returns an objectinitialized from data in a given unarchiver. (required)
从一个给定unarchiver的数据中返回一个初始化对象。
3)copyWithZone
Returnsa new instance that’s a copy of the receiver
返回消息接收者的一个复制的新实例。
3.遵守NSCoding协议,并实现该协议中的两个方法。
4.如果是继承,则子类一定要重写(initWithCoder,encodeWithCoder)那两个方法。因为person的子类在存取的时候,会去子类中去找调用的方法,没找到那么它就去父类中找,所以最后保存和读取的时候新增加的属性会被忽略。需要先调用父类的方法,先初始化父类的,再初始化子类的。
5.保存数据的文件的后缀名可以随意命名。
6.通过plist保存的数据是直接显示的,不安全。通过归档方法保存的数据在文件中打开是乱码的,更安全。
1、plist文件(属性列表),通常用于储存用户设置,也可以用于存储捆绑的信息; 2、preference(偏好设置),常用于保存少量数据; 3、NSKeyedArchiver(归档),将内存中的对象实例保存成binary到磁盘并且可以逆向这个过程用来保存用户操作状态...
数据从内存存储到闪存上
归档这种保存方式缺点就是没有属性列表(NSuserDefault)速度快,因为它每次都要把文件保存到闪存中,优点是可以创建自己想要的数据模型,然后统一以模型方式存储,比属性列表要过分依赖Key要省心。