Objective-C中对象的序列化和反序列化

在Objective-C中要想将对象序列化和反序列化,要做以下三件事情:

1. 该类必须遵循NSCoding协议。

2. 要实现NSCoding的下面两个方法。

- (id)initWithCoder:(NSCoder *)aDecoder

- (void)encodeWithCoder:(NSCoder *)aCoder

备注:一般如果仅仅序列化某一个对象成文件,我们只需要在这两个方法中用key和value存取就可以了,这里也就直接给参考链接了 iOS序列化与反序列化/ ios iphone 如何序列化存储,保存数据我这里给出多个文件都需要序列化的做法(当然这也是项目中以为元老写的,我这里借用他的代码)。

3. 用NSKeyedArchiver进行序列化。代码如下:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object];

附:第二步中,多个文件序列化的做法:

1. 让需要序列化的类都继承自一个基类BaseObject

2. BaseObject遵循NSCoding协议,并实现它的两个方法。如下代码清单所述。

@implementation BaseObject

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        [self codeDataWithCoder:aDecoder isEncoding:YES];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [self codeDataWithCoder:aCoder isEncoding:NO];
}

- (void)codeDataWithCoder:(NSCoder *)coder isEncoding:(BOOL)isEncoding
{
    Class cls = [self class];
    unsigned int numberOfIvars = 0;
    Ivar* ivars = class_copyIvarList(cls, &numberOfIvars);
    for(const Ivar* p = ivars; p < ivars+numberOfIvars; p++)
    {
        Ivar const ivar = *p;
        // 这里应该注意:Any instance variables declared by superclasses are not included
        const char *ivar_type = ivar_getTypeEncoding(ivar);
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
        
        if (isEncoding) {
            NSObject* value = nil;
            
            //For bool value
            if (strcmp(ivar_type, "c") == 0) {
                BOOL boolVal = [coder decodeBoolForKey:key];
                value = [NSNumber numberWithBool:boolVal];
                
                [self setValue:value forKey:key];
            //For NSInteger value
            } else if(strcmp(ivar_type, "i") == 0) {
                NSInteger intVal = [coder decodeIntegerForKey:key];
                value = [NSNumber numberWithInteger:intVal];
                
                [self setValue:value forKey:key];
            } else {
                value = [coder decodeObjectForKey:key];
                
                if(value)
                {
                    NSString* st_property_type = [NSString stringWithCString:ivar_type encoding:NSUTF8StringEncoding];
                    if( [st_property_type hasPrefix:@"@\""] && [st_property_type hasSuffix:@"\""] && st_property_type.length > 3 )
                    {
                        NSRange range = NSMakeRange(2, st_property_type.length - 3);
                        st_property_type = [st_property_type substringWithRange:range];
                    }
                    Class cls_property = NSClassFromString(st_property_type);
                    Class cls_value = [value class];
                    
                    if ( cls_property == cls_value || [cls_property isSubclassOfClass:cls_value] || [cls_value isSubclassOfClass:cls_property] )
                    {
                        [self setValue:value forKey:key];
                    }
                }
            }
        } else {
            //For bool value
            if (strcmp(ivar_type, "c") == 0) {
                BOOL boolVal = [(NSNumber*)[self valueForKey:key] boolValue];
                [coder encodeBool:boolVal forKey:key];
            //For NSInteger value
            } else if(strcmp(ivar_type, "i") == 0) {
                NSInteger intVal = [(NSNumber*)[self valueForKey:key] intValue];
                [coder encodeInteger:intVal forKey:key];
            } else {
                [coder encodeObject:[self valueForKey:key] forKey:key];
            }
        }
    }
    free(ivars);
}

@end

以上代码清单中不清楚的method可以问我,或者直接查看官方文档.

这里还有一篇博文可以参考。对象序列化和反序列化


你可能感兴趣的:(序列化,反序列化,Ivar)