iOS runtime讲解,并且用runtime动态归档与解档

来源:互联网 发布:wine 网络 编辑:程序博客网 时间:2024/05/17 05:59
//
//  AppDelegate.m
//  Runtime自动归档
//
//  Created by CONGAING on 15/7/13.
//  Copyright (c) Congwang. All rights reserved.
//

#import "AppDelegate.h"
#import
 "Student.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (
BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   
 self.window = [[UIWindow alloc] initWithFrame:[[UIScreenmainScreen] bounds]];
   
 // Override point for customization after application launch.
   
 self.window.backgroundColor = [UIColor whiteColor];
    [
self.window makeKeyAndVisible];
   
 //  runtime:运行时机制
   
 //  1.是什么?
   
 //  1.1runtime是一套比较底层的纯C语言的APIruntime就是一个库,一个C语言库,包含了许多底层的C语言API
   
 //  1.2平时我们编写的OC代码,在程序运行过程中,其实最终都是转成了runtimeC语言代码,runtime算是OC的幕后工作者,是整个OC的底层
   
 //  1.3举个例子
   
 //  oc中的代码:[Student alloc] init]经过runtime后,其实最终在底层生成C语言代码:
   
 //  objc_msgSend(objc_msgSend("Student","alloc"), "init")
   
 //  objc_msgSend其实就是想某个对象发送什么消息,这个函数第一个参数是类型或对象名,第二个参数是消息的名字,这些代码比较底层
   
   
 //  2.用过吗?怎么用?
   
 //  2.1 runtime是属于OC的底层,可以进行一些非常底层的操作(用OC无法实现的,或者说不好实现)eg
   
 //  *在程序运行过程中,动态创建一个类,(比如KVOKVC的底层实现)
   
 //  *在程序运行过程中,动态为某个类添加属性/方法,修改属性值,修改方法
   
 //  *遍历一个类中所有的属性和实例变量和所有方法

   
 //  3.
   
 //  3.1相关的头文件
   
 //  #import 
   
 //  #import //消息发送机制,可以直接用底层函数,进行消息发送
   
 //  3.2相关应用
   
 //  *NSCoding(归档和解挡)
   
 //  *字典转模型(利用runtime遍历模型对象的所有属性,根据属性名从字典中取出对应的值,设置到模型的属性上)
   
 //  *kvo(利用runtime动态产生一个类)
   
   
 //  3.3相关函数
   
 //  msg_send:给对象发送消息,来自
   
 //  class_copyMethodList,遍历某个类中所有的方法,来自
   
 //  class_copyIvarList,遍历某个类中所有的实例变量的方法,来自
   
   
 //  运行时必备常识:
   
 //  1.Ivar:成员变量的意思
   
 //  2.Method:成员方法的意思
   
 //  3.property:属性
   
   
 //  下面我们开始实现动态归档
   
 //  打开student.m,引入

   
   
   
 Student *student = [[Student alloc] init];
    student.
name1 = @"sunlin";
    student.
age = 18;
    student.
name2 = @"sunlin";
    student.
name3 = @"sunlin";
    student.
name4 = @"sunlin";
    student.
name5 = @"sunlin";
    student.
name6 = @"sunlin";
    student.
name7 = @"sunlin";
   
 //  归档文件的路径
   
 NSString *filePath = [NSHomeDirectory()stringByAppendingPathComponent:@"person.archiver"];
   
 //  判断该文件是否存在
   
 if (![[NSFileManager defaultManager]fileExistsAtPath:filePath]) {
       
 //  不存在的时候,归档存储一个Student的对象
       
 NSMutableData *data = [NSMutableData data];
       
 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
        [archiver
 encodeObject:student forKey:@"student"];
        [archiver
 finishEncoding];
       
       
 BOOL success = [data writeToFile:filePath atomically:YES];
       
 if (success) {
           
 NSLog(@"归档成功!");
        }
    }
 else{
       
 //  存在的时候,不再进行归档,而是解挡!
       
 NSData *data = [NSData dataWithContentsOfFile:filePath];
       
 NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiveralloc] initForReadingWithData:data];
       
 Student *studentFromSaving = [unArchiverdecodeObjectForKey:@"student"];
       
       
 NSLog(@"%@, %lu", studentFromSaving.name7, studentFromSaving.age);
    }

    return YES;
}

@end


//
//  Student.h
//  Runtime自动归档
//
//  Created by王聪 on 14/7/13.
//  Copyright (c) 2015年congWang. All rights reserved.
//

#import 
#import
 

@interface Student : NSObject<</span>NSCoding>

@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *name1;
@property (nonatomic, copy) NSString *name2;
@property (nonatomic, copy) NSString *name3;
@property (nonatomic, copy) NSString *name4;
@property (nonatomic, copy) NSString *name5;
@property (nonatomic, copy) NSString *name6;
@property (nonatomic, copy) NSString *name7;

@end


//
//  Student.m
//  Runtime自动归档
//
//  Created by 王聪 on 15/7/13.
//  Copyright (c) 2015 王聪. All rights reserved.
//

#import "Student.h"

@implementation Student
- (
void)encodeWithCoder:(NSCoder *)encoder
{
   
 unsigned int count = 0;
   
 //  利用runtime获取实例变量的列表
   
 Ivar *ivars = class_copyIvarList([self class], &count);
   
 for (int i = 0; i < count; i ++) {
       
 //  取出i位置对应的实例变量
       
 Ivar ivar = ivars[i];
       
 //  查看实例变量的名字
       
 const char *name = ivar_getName(ivar);
       
 //  C语言字符串转化为NSString
       
 NSString *nameStr = [NSString stringWithCString:nameencoding:NSUTF8StringEncoding];
       
 //  利用KVC取出属性对应的值
       
 id value = [self valueForKey:nameStr];
       
 //  归档
        [encoder
 encodeObject:value forKey:nameStr];
    }
   
   
 //  记住C语言中copy出来的要进行释放
   
 free(ivars);
   
}

- (
id)initWithCoder:(NSCoder *)decoder
{
   
 if (self = [super init]) {
       
 unsigned int count = 0;
       
 Ivar *ivars = class_copyIvarList([self class], &count);
       
 for (int i = 0; i < count; i ++) {
           
 Ivar ivar = ivars[i];
           
 const char *name = ivar_getName(ivar);
           
           
 //
           
 NSString *key = [NSString stringWithCString:nameencoding:NSUTF8StringEncoding];
           
 id value = [decoder decodeObjectForKey:key];
           
 //  设置到成员变量身上
            [
self setValue:value forKey:key];
        }
       
       
 free(ivars);
    }
   
 return self;
}



@end

0 0
原创粉丝点击