diff --git a/RuntimeDemo.xcodeproj/project.pbxproj b/RuntimeDemo.xcodeproj/project.pbxproj index 3e7f0e0..6292d9a 100644 --- a/RuntimeDemo.xcodeproj/project.pbxproj +++ b/RuntimeDemo.xcodeproj/project.pbxproj @@ -22,6 +22,9 @@ 6980598D1C30D6070021085B /* HYBTestModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6980598C1C30D6070021085B /* HYBTestModel.m */; }; 6980598E1C30D6070021085B /* HYBTestModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6980598C1C30D6070021085B /* HYBTestModel.m */; }; 6980598F1C30D6070021085B /* HYBTestModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6980598C1C30D6070021085B /* HYBTestModel.m */; }; + 698828201C3383F8002363D5 /* HDFArchiveModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6988281F1C3383F8002363D5 /* HDFArchiveModel.m */; }; + 698828211C3383F8002363D5 /* HDFArchiveModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6988281F1C3383F8002363D5 /* HDFArchiveModel.m */; }; + 698828221C3383F8002363D5 /* HDFArchiveModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6988281F1C3383F8002363D5 /* HDFArchiveModel.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -65,6 +68,8 @@ 69654F921C30214500FFB5AC /* UIControl+HYBBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+HYBBlock.m"; sourceTree = ""; }; 6980598B1C30D6070021085B /* HYBTestModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HYBTestModel.h; sourceTree = ""; }; 6980598C1C30D6070021085B /* HYBTestModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HYBTestModel.m; sourceTree = ""; }; + 6988281E1C3383F8002363D5 /* HDFArchiveModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDFArchiveModel.h; sourceTree = ""; }; + 6988281F1C3383F8002363D5 /* HDFArchiveModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HDFArchiveModel.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -127,6 +132,7 @@ 69654F581C2CDE6600FFB5AC /* RuntimeDemo */ = { isa = PBXGroup; children = ( + 6988281D1C3383B4002363D5 /* Archive */, 6980598A1C30D5E90021085B /* Dict-Model */, 69654F5C1C2CDE6600FFB5AC /* AppDelegate.h */, 69654F5D1C2CDE6600FFB5AC /* AppDelegate.m */, @@ -178,6 +184,15 @@ name = "Dict-Model"; sourceTree = ""; }; + 6988281D1C3383B4002363D5 /* Archive */ = { + isa = PBXGroup; + children = ( + 6988281E1C3383F8002363D5 /* HDFArchiveModel.h */, + 6988281F1C3383F8002363D5 /* HDFArchiveModel.m */, + ); + name = Archive; + sourceTree = ""; + }; A4EC37D5D490197569607E30 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -370,6 +385,7 @@ 69654F611C2CDE6600FFB5AC /* ViewController.m in Sources */, 69654F5E1C2CDE6600FFB5AC /* AppDelegate.m in Sources */, 69654F5B1C2CDE6600FFB5AC /* main.m in Sources */, + 698828201C3383F8002363D5 /* HDFArchiveModel.m in Sources */, 6980598D1C30D6070021085B /* HYBTestModel.m in Sources */, 69654F931C30214500FFB5AC /* UIControl+HYBBlock.m in Sources */, ); @@ -380,6 +396,7 @@ buildActionMask = 2147483647; files = ( 69654F741C2CDE6600FFB5AC /* RuntimeDemoTests.m in Sources */, + 698828211C3383F8002363D5 /* HDFArchiveModel.m in Sources */, 69654F941C30214500FFB5AC /* UIControl+HYBBlock.m in Sources */, 6980598E1C30D6070021085B /* HYBTestModel.m in Sources */, ); @@ -390,6 +407,7 @@ buildActionMask = 2147483647; files = ( 69654F7F1C2CDE6600FFB5AC /* RuntimeDemoUITests.m in Sources */, + 698828221C3383F8002363D5 /* HDFArchiveModel.m in Sources */, 69654F951C30214500FFB5AC /* UIControl+HYBBlock.m in Sources */, 6980598F1C30D6070021085B /* HYBTestModel.m in Sources */, ); diff --git a/RuntimeDemo.xcworkspace/xcuserdata/huangyibiao.xcuserdatad/UserInterfaceState.xcuserstate b/RuntimeDemo.xcworkspace/xcuserdata/huangyibiao.xcuserdatad/UserInterfaceState.xcuserstate index fe6f64b..450ef62 100644 Binary files a/RuntimeDemo.xcworkspace/xcuserdata/huangyibiao.xcuserdatad/UserInterfaceState.xcuserstate and b/RuntimeDemo.xcworkspace/xcuserdata/huangyibiao.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/RuntimeDemo/HDFArchiveModel.h b/RuntimeDemo/HDFArchiveModel.h new file mode 100644 index 0000000..f08bb59 --- /dev/null +++ b/RuntimeDemo/HDFArchiveModel.h @@ -0,0 +1,23 @@ +// +// HDFArchiveModel.h +// RuntimeDemo +// +// Created by huangyibiao on 15/12/30. +// Copyright © 2015年 huangyibiao. All rights reserved. +// + +#import +#import "HYBTestModel.h" + +@interface HDFArchiveModel : NSObject + +@property (nonatomic, assign) int referenceCount; +//@property (nonatomic, strong) HYBTestModel *testModel; +@property (nonatomic, copy) NSString *archive; +@property (nonatomic, assign) const void *session; +@property (nonatomic, strong) NSNumber *totalCount; +@property (nonatomic, assign) float _floatValue; + ++ (void)test; + +@end diff --git a/RuntimeDemo/HDFArchiveModel.m b/RuntimeDemo/HDFArchiveModel.m new file mode 100644 index 0000000..92694dc --- /dev/null +++ b/RuntimeDemo/HDFArchiveModel.m @@ -0,0 +1,150 @@ +// +// HDFArchiveModel.m +// RuntimeDemo +// +// Created by huangyibiao on 15/12/30. +// Copyright © 2015年 huangyibiao. All rights reserved. +// + +#import "HDFArchiveModel.h" +#import +#import + +@implementation HDFArchiveModel + +- (void)encodeWithCoder:(NSCoder *)aCoder { + unsigned int outCount = 0; + Ivar *ivars = class_copyIvarList([self class], &outCount); + + for (unsigned int i = 0; i < outCount; ++i) { + Ivar ivar = ivars[i]; + + // 获取成员变量名 + const void *name = ivar_getName(ivar); + NSString *ivarName = [NSString stringWithUTF8String:name]; + // 去掉成员变量的下划线 + ivarName = [ivarName substringFromIndex:1]; + + // 获取getter方法 + SEL getter = NSSelectorFromString(ivarName); + if ([self respondsToSelector:getter]) { + const void *typeEncoding = ivar_getTypeEncoding(ivar); + NSString *type = [NSString stringWithUTF8String:typeEncoding]; + + // const void * + if ([type isEqualToString:@"r^v"]) { + const char *value = ((const void *(*)(id, SEL))(void *)objc_msgSend)((id)self, getter); + NSString *utf8Value = [NSString stringWithUTF8String:value]; + [aCoder encodeObject:utf8Value forKey:ivarName]; + continue; + } + // int + else if ([type isEqualToString:@"i"]) { + int value = ((int (*)(id, SEL))(void *)objc_msgSend)((id)self, getter); + [aCoder encodeObject:@(value) forKey:ivarName]; + continue; + } + // float + else if ([type isEqualToString:@"f"]) { + float value = ((float (*)(id, SEL))(void *)objc_msgSend)((id)self, getter); + [aCoder encodeObject:@(value) forKey:ivarName]; + continue; + } + + id value = ((id (*)(id, SEL))(void *)objc_msgSend)((id)self, getter); + if (value != nil && [value respondsToSelector:@selector(encodeWithCoder:)]) { + [aCoder encodeObject:value forKey:ivarName]; + } + } + } + + free(ivars); +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + unsigned int outCount = 0; + Ivar *ivars = class_copyIvarList([self class], &outCount); + + for (unsigned int i = 0; i < outCount; ++i) { + Ivar ivar = ivars[i]; + + // 获取成员变量名 + const void *name = ivar_getName(ivar); + NSString *ivarName = [NSString stringWithUTF8String:name]; + // 去掉成员变量的下划线 + ivarName = [ivarName substringFromIndex:1]; + // 生成setter格式 + NSString *setterName = ivarName; + // 那么一定是字母开头 + if (![setterName hasPrefix:@"_"]) { + NSString *firstLetter = [NSString stringWithFormat:@"%c", [setterName characterAtIndex:0]]; + setterName = [setterName substringFromIndex:1]; + setterName = [NSString stringWithFormat:@"%@%@", firstLetter.uppercaseString, setterName]; +// [setterName stringByReplacingCharactersInRange:NSMakeRange(0, 0) withString:firstLetter.uppercaseString]; + + } + setterName = [NSString stringWithFormat:@"set%@:", setterName]; + // 获取getter方法 + SEL setter = NSSelectorFromString(setterName); + if ([self respondsToSelector:setter]) { + const void *typeEncoding = ivar_getTypeEncoding(ivar); + NSString *type = [NSString stringWithUTF8String:typeEncoding]; + NSLog(@"%@", type); + + // const void * + if ([type isEqualToString:@"r^v"]) { + NSString *value = [aDecoder decodeObjectForKey:ivarName]; + if (value) { + ((void (*)(id, SEL, const void *))objc_msgSend)(self, setter, value.UTF8String); + } + + continue; + } + // int + else if ([type isEqualToString:@"i"]) { + NSNumber *value = [aDecoder decodeObjectForKey:ivarName]; + if (value != nil) { + ((void (*)(id, SEL, int))objc_msgSend)(self, setter, [value intValue]); + } + continue; + } else if ([type isEqualToString:@"f"]) { + NSNumber *value = [aDecoder decodeObjectForKey:ivarName]; + if (value != nil) { + ((void (*)(id, SEL, float))objc_msgSend)(self, setter, [value floatValue]); + } + continue; + } + + // object + id value = [aDecoder decodeObjectForKey:ivarName]; + if (value != nil) { + ((void (*)(id, SEL, id))objc_msgSend)(self, setter, value); + } + } + } + + free(ivars); + } + + return self; +} + ++ (void)test { + HDFArchiveModel *archiveModel = [[HDFArchiveModel alloc] init]; + archiveModel.archive = @"标哥学习自动归档"; + archiveModel.session = "http://www.henishuo.com"; + archiveModel.totalCount = @(123); + archiveModel.referenceCount = 10; + archiveModel._floatValue = 10.0; + + NSString *path = NSHomeDirectory(); + path = [NSString stringWithFormat:@"%@/archive", path]; + [NSKeyedArchiver archiveRootObject:archiveModel + toFile:path]; + + HDFArchiveModel *unarchiveModel = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; + +} + +@end diff --git a/RuntimeDemo/ViewController.m b/RuntimeDemo/ViewController.m index 50a3ca2..682e82f 100644 --- a/RuntimeDemo/ViewController.m +++ b/RuntimeDemo/ViewController.m @@ -10,6 +10,7 @@ #import #import #import "HYBTestModel.h" +#import "HDFArchiveModel.h" @interface ViewController () @@ -23,7 +24,8 @@ - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. - [HYBTestModel test]; +// [HYBTestModel test]; + [HDFArchiveModel test]; } - (void)didReceiveMemoryWarning {