美文网首页
runtime(1)--ivar,property

runtime(1)--ivar,property

作者: 初灬终 | 来源:发表于2017-12-01 23:59 被阅读5次

    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
    

    相关文章

      网友评论

          本文标题:runtime(1)--ivar,property

          本文链接:https://www.haomeiwen.com/subject/gljgbxtx.html