标签:
mian.m int main(int argc, const char * argv[]) { @autoreleasepool { [[NSObject alloc] init]; } return 0; }使用终端命令行切换到mian.m文件所在的目录下并执行: clang -rewrite-objc main.m
<span style="font-weight: normal;">#import <Foundation/Foundation.h> @interface Person : NSObject @property (copy, nonatomic) NSString *name; @property (copy, nonatomic) NSString *address; @property (assign, nonatomic)int age; @property (assign, nonatomic)double hight; @property (assign, nonatomic)BOOL gender; + (void)run; - (void)study; @end //-------------------------------------------------------------------------------------- #import "Person.h" @implementation Person + (void)run { NSLog(@"run。。。"); } - (void)study { NSLog(@"study..."); } @end //-------------------------------------------------------------------------------------- int main(int argc, const char * argv[]) { @autoreleasepool { Method runMethod = class_getClassMethod([Person class], @selector(run)); Method studyMethod = class_getInstanceMethod([Person class], @selector(study)); method_exchangeImplementations(runMethod, studyMethod); [Person run]; // 打印 study... [[[Person alloc] init] study]; // 打印 run。。。 } return 0; }</span>
#import <Foundation/Foundation.h> #import <objc/runtime.h> @interface Person (AddProperty) @property (copy, nonatomic) NSString *name; @end #import "Person+AddProperty.h" @implementation Person (AddProperty) - (void)setName:(NSString *)name { objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_COPY_NONATOMIC); } - (NSString *)name { return objc_getAssociatedObject(self, "name"); } @end //------------------------------------------------------------------------------ #import <Foundation/Foundation.h> #import "Person+AddProperty.h" #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *person = [[Person alloc] init]; person.name = @"小红"; NSLog(@"使用类别(分类)间接为类添加属性, person.name = %@", person.name); } return 0; }
int main(int argc, const char * argv[]) { @autoreleasepool { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList([Person class], &outCount); for (int i = 0; i < outCount; i++) { Ivar ivar = ivars[i]; const char* name = ivar_getName(ivar); const char* type = ivar_getTypeEncoding(ivar); NSLog(@"%s :%s", name, type); } free(ivars); } return 0; } 2016-07-19 17:48:28.788 Runtime[13864:3404989] _gender :c 2016-07-19 17:48:28.789 Runtime[13864:3404989] _age :i 2016-07-19 17:48:28.789 Runtime[13864:3404989] _address :@"NSString" 2016-07-19 17:48:28.789 Runtime[13864:3404989] _hight :d Program ended with exit code: 0
static void display(id self, SEL _cmd){ NSLog(@"invoke method with selector %@ on %@ instance", NSStringFromSelector(_cmd), [self class]); } int main(int argc, const char * argv[]) { @autoreleasepool { // 1. 创建一个类对 Class WidgetClass = objc_allocateClassPair([NSObject class], "Widget", 0); // 2. 为该类添加一个方法 class_addMethod(WidgetClass, @selector(display), (IMP)display, "v@:"); // 3. 为该类添加一个实例变量 class_addIvar(WidgetClass, "height", sizeof(id), rint(log2(sizeof(id))), @encode(id)); // 4. 注册类对 objc_registerClassPair(WidgetClass); // 5. 创建实例变量并赋值、调用方法 id widge = [[WidgetClass alloc] init]; [widge setValue:@(15) forKey:[NSString stringWithUTF8String:"height"]]; NSLog(@"Widge instance height = %@", [widge valueForKey:[NSString stringWithUTF8String:"height"]]); objc_msgSend(widge, NSSelectorFromString(@"display")); // 6. 动态方式添加一个属性 objc_setAssociatedObject(widge, @"width", @(10), OBJC_ASSOCIATION_RETAIN_NONATOMIC); // 7. 获取 id result = objc_getAssociatedObject(widge, @"width"); NSLog(@"Widget instance width = %@", result); } return 0; }
#import <Foundation/Foundation.h> @interface Student : NSObject <NSCoding> @property (copy, nonatomic) NSString *name; @property (assign, nonatomic)int age; @property (assign, nonatomic)double weight; @property (copy, nonatomic)NSArray *hobby; @property (copy, nonatomic)NSDictionary *others; @end #import "Student.h" #define knameKey @"name" #define kageKey @"age" #define kweightKey @"weight" #define khobbyKey @"hobby" #define kothersKey @"others" @implementation Student - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:_name forKey:knameKey]; [aCoder encodeInt:_age forKey:kageKey]; [aCoder encodeDouble:_weight forKey:kweightKey]; [aCoder encodeObject:_hobby forKey:khobbyKey]; [aCoder encodeObject:_others forKey:kothersKey]; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { _name = [aDecoder decodeObjectForKey:knameKey]; _age = [aDecoder decodeIntForKey:kageKey]; _weight = [aDecoder decodeDoubleForKey:kweightKey]; _hobby = [aDecoder decodeObjectForKey:khobbyKey]; _others = [aDecoder decodeObjectForKey:kothersKey]; } return self; } @end int main(int argc, const char * argv[]) { @autoreleasepool { Student *student = [[Student alloc] init]; student.name = @"小红"; student.age = 25; student.weight = 100.5; student.hobby = @[@"吃", @"喝", @"玩", @"乐"]; student.others = @{@"phone": @"1234567890", @"wechat": @"123456"}; NSString *path = @"/Users/macmini/Documents/Test/Student.plist"; [NSKeyedArchiver archiveRootObject:student toFile:path]; Student *xiaoming = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@"xiaoming:%@", xiaoming); } return 0; }
#import "Student.h" #import <objc/runtime.h> @implementation Student // 获取所有成员变量进行循环编码 - (void)encodeWithCoder:(NSCoder *)aCoder { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i++) { NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])]; id value = [self valueForKey:key]; [aCoder encodeObject:value forKey:key]; } free(ivars); } - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList([self class], &outCount); for (int i = 0; i < outCount; i++) { NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])]; id value = [self valueForKey:key]; [self setValue:value forKey:key]; } free(ivars); } return self; } @end普通写法每个类都要写一次,使用runtime虽然每个类都要写一次,但是代码都是完全一样的,可以直接粘贴复制,
//该实现也实现了对父类属性进行归档解档的实现 #import "NSObject+Archive.h" #import <objc/runtime.h> @implementation NSObject (Archive) // 先对当前类进行编码,然后对父类进行编码,如果父类是NSObject就结束编码 - (void)encode:(NSCoder *)aCoder { Class clazz = self.class; while (clazz && clazz != [NSObject class]) { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList(clazz, &outCount); for (int i = 0; i < outCount; i++) { NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])]; id value = [self valueForKey:key]; [aCoder encodeObject:value forKey:key]; } free(ivars); clazz = [clazz superclass]; } } - (void)decode:(NSCoder *)aDecoder { Class clazz = self.class; while (clazz && clazz != [NSObject class]) { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList(clazz, &outCount); for (int i = 0; i < outCount; i++) { NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])]; id value = [aDecoder decodeObjectForKey:key]; [self setValue:value forKey:key]; } free(ivars); clazz = [clazz superclass]; } } @end
#import <Foundation/Foundation.h> #import "Person.h" // 继承Person类 @interface Student : Person <NSCoding> @property (copy, nonatomic) NSString *name; @property (assign, nonatomic)double weight; @property (copy, nonatomic)NSArray *hobby; @property (copy, nonatomic)NSDictionary *others; @end #import "Student.h" #import "NSObject+Archive.h" #import <objc/runtime.h> @implementation Student - (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { [self decode:aDecoder]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { [self encode:aCoder]; } @end int main(int argc, const char * argv[]) { @autoreleasepool { Student *student = [[Student alloc] init]; student.name = @"小红"; student.age = 25; student.weight = 100.5; student.hobby = @[@"吃", @"喝", @"玩", @"乐"]; student.others = @{@"phone": @"1234567890", @"wechat": @"123456"}; student.address = @"父类属性address"; student.hight = 180.5; student.gender = YES; NSString *path = @"/Users/macmini/Documents/Test/Student.plist"; [NSKeyedArchiver archiveRootObject:student toFile:path]; Student *xiaoming = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@"xiaoming:%@", xiaoming); } return 0; }
#ifndef Coding_h #define Coding_h #import "NSObject+Archive.h" #define CodingImplemention - (instancetype)initWithCoder:(NSCoder *)aDecoder {if (self = [super init]) { [self decode:aDecoder];} return self;}- (void)encodeWithCoder:(NSCoder *)aCoder { [self encode:aCoder];} #endif /* Coding_h */
#import "Student.h" #import "Coding.h" @implementation Student CodingImplemention @end在Student.m 文件中只需一个单词即可实现归档解档,可以看到已经达到至简了
@interface School : NSObject @property (copy, nonatomic)NSString * ID; @property (copy, nonatomic)NSString * name; @end #import "School.h" @implementation School @end
#import <Foundation/Foundation.h> @interface Address : NSObject @property (copy, nonatomic)NSString * ID; @property (copy, nonatomic)NSString * address; @end #import "Address.h" @implementation Address @end
#import <Foundation/Foundation.h> #import "School.h" @interface User : NSObject @property (copy, nonatomic)NSString * ID; @property (copy, nonatomic)NSString * name; @property (assign, nonatomic)int age; @property (strong, nonatomic)School *school; @property (copy, nonatomic)NSArray *address; @end #import "User.h" @implementation User - (NSDictionary *)eleTypeForArray { return @{@"address": @"Address"}; } @end
#import <Foundation/Foundation.h> @interface NSObject (Dict2Model) - (void)setDict:(NSDictionary *)dict; + (instancetype)initWithDict:(NSDictionary *)dict; - (NSDictionary *)eleTypeForArray; @end #import "NSObject+Dict2Model.h" #import <objc/runtime.h> @implementation NSObject (Dict2Model) - (void)setDict:(NSDictionary *)dict { Class clazz = self.class; while (clazz && clazz != [NSObject class]) { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList(clazz, &outCount); for (int i = 0; i < outCount; i++) { Ivar ivar = ivars[i]; NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; key = [key substringFromIndex:1]; // 去掉实例变量中的下划线 id value = dict[key]; NSLog(@"%d: key:%@ value:%@", i, key, value); // 1. 如果类的实例变量多于字典中key if (value == nil) { continue; } // 2. 实例变量类型以@开头并且前缀不是NS开头的(排除系统类) "@Student" NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; NSRange range = [type rangeOfString:@"@"]; if (range.location != NSNotFound) { type = [type substringWithRange:NSMakeRange(2, type.length - 3)]; if (![type hasPrefix:@"NS"]) { Class class = NSClassFromString(type); value = [class initWithDict:value]; } else if ([type isEqualToString:@"NSArray"]) { NSArray *array = (NSArray *)value; NSMutableArray *mArray = [NSMutableArray array]; id class; if ([self respondsToSelector:@selector(eleTypeForArray)]) { NSString *eleTypeStr = [[self eleTypeForArray] objectForKey:key]; class = NSClassFromString(eleTypeStr); } else { NSLog(@"数组类型不明确!"); return; } for (int i = 0; i < array.count; i++) { id obj = [class initWithDict:value[i]]; [mArray addObject:obj]; } value = mArray; } } [self setValue:value forKeyPath:key]; } free(ivars); clazz = [clazz superclass]; } } + (instancetype)initWithDict:(NSDictionary *)dict { NSObject *obj = [[self alloc] init]; [obj setDict:dict]; return obj; } @end
Student.json { "name" : "Tom", "age" : 20, "weight" : "181", "school":{ "ID":1, "name":"北京大学" }, "address" : [ { "ID":1, "address":"上海市" }, { "ID":2, "address":"北京市" } ] }
int main(int argc, const char * argv[]) { @autoreleasepool { NSData *jsonData = [NSData dataWithContentsOfFile:@"/Users/macmini/Documents/Test/RuntimeWidget/RuntimeWidget/Student.json"]; NSDictionary *userDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL]; User *user = (User *)[User initWithDict:userDict]; School *school = user.school; Address *address = user.address[0]; NSLog(@"User: %@, %d, %@, %@", user.name, user.age, school.name, address.address); } return 0; }
标签:
原文地址:http://blog.csdn.net/vbirdbest/article/details/51980161