runtime(1)--ivar,property

2017-12-01  本文已影响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
上一篇 下一篇

猜你喜欢

热点阅读