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

//
//  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 :[[ UIScreen mainScreen ]  bounds ]];
   
  // Override point for customization after application launch.
   
  self . window . backgroundColor  = [ UIColor  whiteColor ];
    [
self . window  makeKeyAndVisible ];
   
  //  runtime: 运行时机制
   
  //  1. 是什么?
   
  //  1.1runtime 是一套比较底层的纯 C 语言的 API runtime 就是一个库,一个 C 语言库,包含了许多底层的 C 语言 API
   
  //  1.2 平时我们编写的 OC 代码,在程序运行过程中,其实最终都是转成了 runtime C 语言代码, 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
   
  //  * 在程序运行过程中,动态创建一个类,(比如 KVO KVC 的底层实现)
   
  //  * 在程序运行过程中,动态为某个类添加属性/方法,修改属性值,修改方法
   
  //  * 遍历一个类中所有的属性和实例变量和所有方法

   
  //  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 = [[ NSKeyedUnarchiver alloc ]  initForReadingWithData :data];
       
  Student  *studentFromSaving = [unArchiver decodeObjectForKey : @"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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值