OC学习笔记之008文件IO

1.NSData与NSMutableData

这两个data的作用是讲将数据读入nsdata,并使用nsdata输出数据
在这里插入图片描述

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    //使用nsdata读取指定url对应的数据
    NSData* data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.baidu.com"]];
    NSLog(@"%ld",data.length);
    
    //定义一个长度为100的数组
    char buffer[200];
    //将nsData指定范围的数据读入数组
    [data getBytes:buffer range:NSMakeRange(2, 200)];
    NSLog(@"%s",buffer);
    //直接将nsdata的数据用utf-8的格式转换为字符串
    NSString* content=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"-----输出网页内容-----");
    NSLog(@"%@",content);
  }
  
}

输出:

2020-05-24 11:05:32.105720+0800 EX003[969:39607] 227
2020-05-24 11:05:32.105824+0800 EX003[969:39607] tml>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></no\M-~
2020-05-24 11:05:32.105928+0800 EX003[969:39607] -----输出网页内容-----
2020-05-24 11:05:32.105984+0800 EX003[969:39607] <html>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
2.NSFileManage管理文件和目录

关于路径:

  • 相对路径:不以斜线开头的都是相对路径,如codes/test.m
  • 绝对路径:以斜线 / 开头的路径就是绝对路径,如/users/abc 代表根目录下的abc子目录
    macOS中的几个特殊路径
    ~ :表示用户的home目录
    . :代表当前目录
    … : 代表上级目录
3.访问文件属性和内容

在这里插入图片描述

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSFileManager* fm=[NSFileManager defaultManager];
    //总是看不到自己的文件,输出不具备参考价值
    //判断文件是否存在
    NSLog(@"测试main.m文件是否存在:%d",[fm fileExistsAtPath:@"main.m"]);//总是看不到自己
    BOOL isDir;
    NSLog(@"测试main.m文件是否存在:%d",[fm fileExistsAtPath:@"main.m" isDirectory:&isDir]);//总是看不到自己
    NSLog(@"测试main.m是否为目录:%d",isDir);//总是看不到自己
    //是否为可读目录
    NSLog(@"测试main.m文件是否为可读存在:%d",[fm isReadableFileAtPath:@"main.m"]);
    //是否为可写目录
    NSLog(@"测试main.m文件是否为可写存在:%d",[fm isWritableFileAtPath:@"main.m"]);
    //是否为可执行目录
    NSLog(@"测试main.m文件是否为可执行性:%d",[fm isExecutableFileAtPath:@"main.m"]);
    //是否为可删除目录
    NSLog(@"测试main.m文件是否为删除:%d",[fm isDeletableFileAtPath:@"main.m"]);
    NSArray* array=[fm componentsToDisplayForPath:@"main.m"];
    NSLog(@"------main.m所在完整路径组件为------");
    for (NSObject* object in array) {
      NSLog(@"%@,",object);
    }//无法显示
    NSDictionary* attr=[fm attributesOfItemAtPath:@"main.m" error:nil];
    //获取文件属性详情
    NSLog(@"main.m文件创建时间为:%@",[attr fileCreationDate]);
    NSLog(@"main.m文件所属主账户为:%@",[attr fileOwnerAccountID]);
    NSLog(@"main.m文件文件大小为:%lld",[attr fileSize]);
    
    //直接获取文件内容
    NSData* data=[fm contentsAtPath:@"main.m"];
    //data使用utf8转换
    NSString* str=[ [NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] ;
    NSLog(@"----输出文件内容---");
    NSLog(@"%@",str);
  }
  
}

输出:
2020-05-24 12:43:32.587125+0800 EX003[1298:67794] 测试main.m文件是否存在:0
2020-05-24 12:43:32.587449+0800 EX003[1298:67794] 测试main.m文件是否存在:0
2020-05-24 12:43:32.587482+0800 EX003[1298:67794] 测试main.m是否为目录:0
2020-05-24 12:43:32.587511+0800 EX003[1298:67794] 测试main.m文件是否为可读存在:0
2020-05-24 12:43:32.587536+0800 EX003[1298:67794] 测试main.m文件是否为可写存在:0
2020-05-24 12:43:32.587559+0800 EX003[1298:67794] 测试main.m文件是否为可执行性:0
2020-05-24 12:43:32.587652+0800 EX003[1298:67794] 测试main.m文件是否为删除:1
2020-05-24 12:43:32.593396+0800 EX003[1298:67794] ------main.m所在完整路径组件为------
2020-05-24 12:43:32.593466+0800 EX003[1298:67794] main.m文件创建时间为:(null)
2020-05-24 12:43:32.593494+0800 EX003[1298:67794] main.m文件所属主账户为:(null)
2020-05-24 12:43:32.593546+0800 EX003[1298:67794] main.m文件文件大小为:0
2020-05-24 12:43:32.593596+0800 EX003[1298:67794] ----输出文件内容—
2020-05-24 12:43:32.593636+0800 EX003[1298:67794]

4.NSFileManage创建、删除、移动、复制

在这里插入图片描述

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSFileManager* fm=[NSFileManager defaultManager];
    //创建目录,如果withIntermediateDirectories不存在,则创建目录
    [fm createDirectoryAtPath:@"xyz/abc" withIntermediateDirectories:YES attributes:nil error:nil];
    NSString* content=@"《疯狂ios》是我正在学习的图书";
    [fm createFileAtPath:@"myinfo.txt" contents:[content dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
    //复制一份新文件
    [fm copyItemAtPath:@"myinfo.txt" toPath:@"copyinfo.txt" error:nil];   
  }
}

输出
2020-05-25 10:42:04.539822+0800 EX003[1122:36237] open on copyinfo.txt: File exists
PS:为什么就是找不到这个文件夹呢

5.查看目录包含的内容

在这里插入图片描述

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSFileManager* fm=[NSFileManager defaultManager];
    //获取指定目录下的所有文件和文件夹
    NSArray* array=[fm contentsOfDirectoryAtPath:@"." error:nil];
    for (NSString* str in array) {
      NSLog(@"%@",str);
    }

    
    //获取指定目录下所有文件和文件夹对应的枚举器
    NSDirectoryEnumerator* dirEnum=[fm enumeratorAtPath:@"."];
    NSString* file;
    //枚举dirEnum中包含的每个恩建
    while (file=[dirEnum nextObject]) {
      //如果该文件的文件名义.m结尾
      if ([[file pathExtension] isEqualToString:@"m"]) {
        //直接获取文件内容
        NSData* data=[fm contentsAtPath:file];
        //直接将nsData的数据用utf-8的格式转换为字符串
        NSString* content=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"------------");
        NSLog(@"%@",content);
      }
    }
    
    //获取当前目录下的所有子目录
    //NSArray* subArr=[fm subpathsOfDirectoryAtPath:@"." error:nil];
    NSArray* subArr=[fm subpathsAtPath:@"."];
    for (NSString* item in subArr) {
      NSLog(@"%@",item);
    }
    
  }
  
}

输出:
2020-05-25 15:48:48.053960+0800 EX003[2391:108011] copyinfo.txt
2020-05-25 15:48:48.054264+0800 EX003[2391:108011] abc
2020-05-25 15:48:48.054300+0800 EX003[2391:108011] xyz
2020-05-25 15:48:48.054322+0800 EX003[2391:108011] EX003
2020-05-25 15:48:48.054341+0800 EX003[2391:108011] myinfo.m
2020-05-25 15:48:48.054365+0800 EX003[2391:108011] myinfo.txt
2020-05-25 15:48:48.054385+0800 EX003[2391:108011] myFile.txt
2020-05-25 15:48:48.054403+0800 EX003[2391:108011] copyinfo.m
2020-05-25 15:48:48.055057+0800 EX003[2391:108011] ------------
2020-05-25 15:48:48.055113+0800 EX003[2391:108011] 《疯狂ios》是我正在学习的图书
2020-05-25 15:48:48.055196+0800 EX003[2391:108011] ------------
2020-05-25 15:48:48.055232+0800 EX003[2391:108011] 《疯狂ios》是我正在学习的图书
2020-05-25 15:48:48.055705+0800 EX003[2391:108011] copyinfo.txt
2020-05-25 15:48:48.055744+0800 EX003[2391:108011] abc
2020-05-25 15:48:48.055768+0800 EX003[2391:108011] xyz
2020-05-25 15:48:48.055801+0800 EX003[2391:108011] xyz/abc
2020-05-25 15:48:48.055821+0800 EX003[2391:108011] EX003
2020-05-25 15:48:48.055840+0800 EX003[2391:108011] myinfo.m
2020-05-25 15:48:48.055857+0800 EX003[2391:108011] myinfo.txt
2020-05-25 15:48:48.055876+0800 EX003[2391:108011] myFile.txt
2020-05-25 15:48:48.058264+0800 EX003[2391:108011] copyinfo.m

6.使用nspathUtilities.h管理路径

在这里插入图片描述

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSLog(@"当前用户名:%@",NSUserName());
    NSLog(@"当前完整用户名:%@",NSFullUserName());
    NSLog(@"当前用户的home目录为%@",NSHomeDirectory());
    NSLog(@"root用户的home目录为%@",NSHomeDirectoryForUser(@"root"));
    NSLog(@"系统临时目录%@",NSTemporaryDirectory());
    
    NSString* path=@"~root";
    //将~root解析成root用户的home目录
    NSLog(@"解析~root的结果:%@",[path stringByExpandingTildeInPath]);
    
    NSString* path2=@"/Users/yeeku/publish";
    //将会输出~/publish
    NSLog(@"替换成~的形成:%@",[path2 stringByAbbreviatingWithTildeInPath]);
    NSArray* array=[path2 pathComponents];
    //遍历概路径中包含的各路径组件
    for (NSString* item in array) {
      NSLog(@"%@",item);
    }
    
    //path2路径后追加一个路径
    NSString* path3= [path2 stringByAppendingPathComponent:@"abc.m"];
    NSLog(@"path3为:%@",path3);
    //获取路径的最后部分
    NSString* last=[path3 lastPathComponent];
    NSLog(@"path3的最后一个路径组件为:%@",last);
    //获取路径的最后部分的扩展名
    NSLog(@"path3的最后一个路径的扩展名:%@",[path3 pathExtension]);
  }
  
}

输出:
2020-05-25 17:13:34.599388+0800 EX003[2606:131783] 当前用户名:jian
2020-05-25 17:13:34.599734+0800 EX003[2606:131783] 当前完整用户名:JIAN
2020-05-25 17:13:34.599829+0800 EX003[2606:131783] 当前用户的home目录为/Users/jian
2020-05-25 17:13:34.600034+0800 EX003[2606:131783] root用户的home目录为/var/root
2020-05-25 17:13:34.600410+0800 EX003[2606:131783] 系统临时目录/var/folders/bq/vr96c8z151b3ktmz1xs3qdf00000gn/T/
2020-05-25 17:13:34.600467+0800 EX003[2606:131783] 解析~root的结果:/var/root
2020-05-25 17:13:34.600506+0800 EX003[2606:131783] 替换成~的形成:/Users/yeeku/publish
2020-05-25 17:13:34.600562+0800 EX003[2606:131783] /
2020-05-25 17:13:34.600587+0800 EX003[2606:131783] Users
2020-05-25 17:13:34.600606+0800 EX003[2606:131783] yeeku
2020-05-25 17:13:34.600625+0800 EX003[2606:131783] publish
2020-05-25 17:13:34.600648+0800 EX003[2606:131783] path3为:/Users/yeeku/publish/abc.m
2020-05-25 17:13:34.600672+0800 EX003[2606:131783] path3的最后一个路径组件为:abc.m
2020-05-25 17:13:34.600700+0800 EX003[2606:131783] path3的最后一个路径的扩展名:m

7.使用NSProcessInfo获取进程信息

在这里插入图片描述

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSProcessInfo* proinfo=[NSProcessInfo processInfo];
    //获取运行该程序所指的参数
    NSArray* arr=[proinfo arguments];
    NSLog(@"运行程序的参数为:%@",arr);
    NSLog(@"进程标识符为:%d",[proinfo processIdentifier]);
    NSLog(@"进程名为:%@",[proinfo processName]);
    NSLog(@"进程主机名为:%@",[proinfo hostName]);
    
    NSOperatingSystemVersion version=[proinfo operatingSystemVersion];
    NSLog(@"进程所在系统的操作系统主版本为:%ld",version.majorVersion);
    NSLog(@"进程所在系统的操作系统次版本为:%ld",version.minorVersion);
    NSLog(@"进程所在系统的操作系统补丁版本为:%ld",version.patchVersion);
    NSLog(@"进程所在系统的操作系统字符串为:%@",[proinfo operatingSystemVersionString]);
    NSLog(@"进程所在系统的操作系统物理内存为:%lld",[proinfo physicalMemory]);
    NSLog(@"进程所在系统的操作系统处理器数量为:%ld",[proinfo processorCount]);
    NSLog(@"进程所在系统的操作系统激活的处理器数量为:%ld",[proinfo activeProcessorCount]);
    NSLog(@"进程所在系统的运行时间为:%f",[proinfo systemUptime]);

  }
  
}

输出:
2020-05-25 17:44:00.200624+0800 EX003[2661:140876] 运行程序的参数为:(
“/Users/jian/Library/Developer/Xcode/DerivedData/EX003-gttgjyrabgrfiibfhakhhgwvvktf/Build/Products/Debug/EX003”
)
2020-05-25 17:44:00.200931+0800 EX003[2661:140876] 进程标识符为:2661
2020-05-25 17:44:00.200981+0800 EX003[2661:140876] 进程名为:EX003
2020-05-25 17:44:00.545600+0800 EX003[2661:140876] 进程主机名为:JIANs-MacBook-Pro.local
2020-05-25 17:44:00.550918+0800 EX003[2661:140876] 进程所在系统的操作系统主版本为:10
2020-05-25 17:44:00.550991+0800 EX003[2661:140876] 进程所在系统的操作系统次版本为:15
2020-05-25 17:44:00.551028+0800 EX003[2661:140876] 进程所在系统的操作系统补丁版本为:2
2020-05-25 17:44:00.551064+0800 EX003[2661:140876] 进程所在系统的操作系统字符串为:Version 10.15.2 (Build 19C57)
2020-05-25 17:44:00.551104+0800 EX003[2661:140876] 进程所在系统的操作系统物理内存为:17179869184
2020-05-25 17:44:00.551141+0800 EX003[2661:140876] 进程所在系统的操作系统处理器数量为:6
2020-05-25 17:44:00.551175+0800 EX003[2661:140876] 进程所在系统的操作系统激活的处理器数量为:6
2020-05-25 17:44:00.551208+0800 EX003[2661:140876] 进程所在系统的运行时间为:30883.161527

8.使用NSFileHandle处理文件IO

使用NSFileHandle的基本步骤如下:
1、创建一个NSFileHandle,概NSFileHandle将会打开指定文件
2、对打开的文件执行IO操作
3、关闭文件
NSFileHandle大致提供了如下的常用方法
在这里插入图片描述
文件指针的操作
在这里插入图片描述

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSFileHandle* fh=[NSFileHandle fileHandleForReadingAtPath:@"copyinfo.m"];
    NSData* data;
    //读取NSFileHandle中的256个字节
    while ([(data=[fh readDataOfLength:512]) length]>0) {
      NSLog(@"%ld",[data length]);
      //直接将将nsdata的数据用utf-8的格式转换为字符串
      NSString* content=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
      NSLog(@"-------输出读取的512字节的内容----------");
      NSLog(@"%@",content);
    }
    [fh closeFile];
    //打开一个文件准备写入
    NSFileHandle* fh2=[NSFileHandle fileHandleForWritingAtPath:@"copyinfo.txt"];
    if (!fh2) {
      //创建一个NSFileManage对象
      NSFileManager* fm=[NSFileManager defaultManager];
      //创建一个空的文件
      [fm createFileAtPath:@"abcd.txt" contents:nil attributes:nil];
      fh2=[NSFileHandle fileHandleForWritingAtPath:@"copyinfo.txt"];
      [fh2 seekToEndOfFile];//将文件指着移动到文件的结尾处
      
      NSString* mybook=@"疯狂的ios和android讲义";
      //将指定内容写入底层文件
      [fh2 writeData:[mybook dataUsingEncoding:NSUTF8StringEncoding] ];
      //关闭文件
      [fh2 closeFile];
    }
    
  }
  
}

输出:
2020-05-25 19:50:51.705998+0800 EX003[3209:192337] 42
2020-05-25 19:50:51.706285+0800 EX003[3209:192337] -------输出读取的512字节的内容----------
2020-05-25 19:50:51.706337+0800 EX003[3209:192337] 《疯狂ios》是我正在学习的图书

9.使用NSURL读取网络资源

URL格式为:scheme://host:port/path
以下案例之前的知识点演示过

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    NSURL* url=[NSURL URLWithString:@"http://www.baidu.com"];
    NSLog(@"url的scheme为:%@",[url scheme]);
    NSLog(@"url的host为:%@",[url host]);
    NSLog(@"url的port为:%@",[url port]);
    NSLog(@"url的path为:%@",[url path]);
    
    //使用URL对应的资源来初始化NSString对象
    NSString* homePage=[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%@",homePage);

    
  }
  
}

输出:

2020-05-25 19:58:41.101309+0800 EX003[3279:197647] url的scheme为:http
2020-05-25 19:58:41.101617+0800 EX003[3279:197647] url的host为:www.baidu.com
2020-05-25 19:58:41.101652+0800 EX003[3279:197647] url的port为:(null)
2020-05-25 19:58:41.101683+0800 EX003[3279:197647] url的path为:
2020-05-25 19:58:41.186122+0800 EX003[3279:197647] <html>
<head>
	<script>
		location.replace(location.href.replace("https://","http://"));
	</script>
</head>
<body>
	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
10.使用NSBundle处理项目相关资源
int main(int argc, const char * argv[]) {
  @autoreleasepool {
    //使用NSBundle获取该应用自包含的指定资源文件的路径
    NSString* filepath=[[NSBundle mainBundle]pathForResource:@"copyinfo.txt" ofType:@"txt"];
    //使用指定文件的内容来初始化NSString
    NSString* content=[NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:nil];
    //显示content字符串的内容
    NSLog(@"%@",content);

  }
  
}

还是无法实现。

11.对象归档(对象转文件)

类似于其他语言的序列化,归档就是用某种格式把一个或者多个对象保存到指定文件中,方便以后从文件中恢复,归档包含两方面操作
一方面把对象写入指定文件
另一方面把文件中的内容恢复成对象

12.使用NSKeyedArchiver

通过键值的形式对对象进行检索
在这里插入图片描述

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    //使用简化语法创建nsdictionary对象
    NSDictionary* dict=@{
      @"Object-c":[NSNumber numberWithInt:89],
      @"Ruby":[NSNumber numberWithInt:69],
      @"Python":[NSNumber numberWithInt:75],
      @"Perl":[NSNumber numberWithInt:109]
    };
    
    //对dict对象进行归档
    [NSKeyedArchiver archiveRootObject:dict toFile:@"mydict.archice"];//该方法已经过时
    //对序列化文档进行反归档,生成对象
    NSDictionary* dict2=[NSKeyedUnarchiver unarchiveObjectWithFile:@"mydict.archice"];
    //获取键值对
    NSLog(@"Object-c对应的value:%@",dict[@"Object-c"]);
    NSLog(@"Ruby对应的value:%@",dict[@"Ruby"]);
    NSLog(@"Python对应的value:%@",dict[@"Python"]);
    NSLog(@"Perl对应的value:%@",dict[@"Perl"]);

  }
  
}

输出:
2020-05-26 00:25:33.323969+0800 EX003[4181:293839] Object-c对应的value:89
2020-05-26 00:25:33.324265+0800 EX003[4181:293839] Ruby对应的value:69
2020-05-26 00:25:33.324301+0800 EX003[4181:293839] Python对应的value:75
2020-05-26 00:25:33.324340+0800 EX003[4181:293839] Perl对应的value:109

13.使用NSCoding协议

在这里插入图片描述

#import <Foundation/Foundation.h>
@interface Apple:NSObject<NSCoding>
@property(nonatomic,copy)NSString* color;
@property(nonatomic,assign)double weight;
@property(nonatomic,assign)int size;
-(id)initWithColor:(NSString *)color weight:(double)weight size:(int)size;
@end

@implementation Apple

-(id)initWithColor:(NSString *)color weight:(double)weight size:(int)size{
  if (self=[super init]) {
    self.color=color;
    self.weight=weight;
    self.size=size;
  }
  return self;
}

//重写父类的desription方法
-(NSString*)description{
  //返回一个字符串
  return [NSString stringWithFormat:@"<Apple【_color=%@,_weight=%g,_size=%d】>",self.color,self.weight,self.size];
}

-(void)encodeWithCoder:(NSCoder *)coder{
  //调用NSCoder的方法归档该对象的每一个成员变量
  [coder encodeObject:_color forKey:@"color"];
  [coder encodeDouble:_weight forKey:@"weight"];
  [coder encodeInt:_size forKey:@"size"];
}

-(id)initWithCoder:(NSCoder*)coder{
  //使用NScoder依次恢复color,weight,size这3个key
  //所对应的value,并将恢复的value赋给当前对象的3个成员变量
  _color=[coder decodeObjectForKey:@"color"];
  _weight=[coder decodeDoubleForKey:@"weight"];
  _size=[coder decodeIntForKey:@"size"];
  return self;
}

@end
int main(int argc, const char * argv[]) {
  @autoreleasepool {
   //创建Apple对象
    Apple* apple=[[Apple alloc]initWithColor:@"红色" weight:3.4 size:20];
   //对apple对象进行归档
    [NSKeyedArchiver archiveRootObject:apple toFile:@"apple.archive"];
    
    Apple* apple2=[NSKeyedUnarchiver unarchiveObjectWithFile:@"apple.archive"];
    //获取对象属性
    NSLog(@"苹果的颜色为:%@",apple2.color);
    NSLog(@"苹果的颜色为:%g",apple2.weight);
    NSLog(@"苹果的颜色为:%d",apple2.size);
  }
  
}

输出:
2020-05-26 01:01:05.273863+0800 EX003[4331:312412] 苹果的颜色为:红色
2020-05-26 01:01:05.274183+0800 EX003[4331:312412] 苹果的颜色为:3.4
2020-05-26 01:01:05.274219+0800 EX003[4331:312412] 苹果的颜色为:20

14.使用NSData完成自定义归档

借助NSMustableData来创建NSkeyedArchiver或NSKeyUnarchiver对象
归档按照如下步骤来
1、以NSMutableData作为参数,创建NSKeyedArchiver对象
2、重复调用NSkeyedArchiver对象的encodeXXX:forKey:方法来归档所有需要归档到一个文件的对象
3、调用NSkeyedArchiver对象的finishEncoding方法结束归档
4、根据需要,程序可以选择将保存归档数据的NSData通过网络传输或输出到磁盘文件上

反归档按照如下步骤来
1、以NSMutableData作为参数,创建NSKeyedUnarchiver对象
2、重复调用NSkeyedUnarchiver对象的decodeXXX:forKey:方法从一个文件中恢复所有归档过的对象
3、调用NSkeyedUnarchiver对象的finishDecoding方法结束恢复

#import <Foundation/Foundation.h>
@interface Apple:NSObject<NSCoding>
@property(nonatomic,copy)NSString* color;
@property(nonatomic,assign)double weight;
@property(nonatomic,assign)int size;
-(id)initWithColor:(NSString *)color weight:(double)weight size:(int)size;
@end

@implementation Apple

-(id)initWithColor:(NSString *)color weight:(double)weight size:(int)size{
  if (self=[super init]) {
    self.color=color;
    self.weight=weight;
    self.size=size;
  }
  return self;
}

//重写父类的desription方法
-(NSString*)description{
  //返回一个字符串
  return [NSString stringWithFormat:@"<Apple【_color=%@,_weight=%g,_size=%d】>",self.color,self.weight,self.size];
}

-(void)encodeWithCoder:(NSCoder *)coder{
  //调用NSCoder的方法归档该对象的每一个成员变量
  [coder encodeObject:_color forKey:@"color"];
  [coder encodeDouble:_weight forKey:@"weight"];
  [coder encodeInt:_size forKey:@"size"];
}

-(id)initWithCoder:(NSCoder*)coder{
  //使用NScoder依次恢复color,weight,size这3个key
  //所对应的value,并将恢复的value赋给当前对象的3个成员变量
  _color=[coder decodeObjectForKey:@"color"];
  _weight=[coder decodeDoubleForKey:@"weight"];
  _size=[coder decodeIntForKey:@"size"];
  return self;
}

@end
int main(int argc, const char * argv[]) {
  @autoreleasepool {
   //创建Apple对象
    Apple* apple=[[Apple alloc]initWithColor:@"红色" weight:3.4 size:20];
   //创建一个字典
    NSDictionary* dict=@{
      @"Object-c":[NSNumber numberWithInt:89],
      @"Ruby":[NSNumber numberWithInt:69],
      @"Python":[NSNumber numberWithInt:75],
      @"Perl":[NSNumber numberWithInt:109]
    };
   //创建一个NSSet对象
   NSSet* set=[NSSet setWithObjects:@"疯狂IOS讲义",@"疯狂Android讲义",@"疯狂Ajax讲义",@"疯狂XML讲义",nil];
   //创建一个NSMutableData对象,用于保存归档数据
    NSMutableData* data=[NSMutableData data];
    //以NSMutableData对象作为参数,创建一个NSKeyedArchiver对象
    NSKeyedArchiver* arch=[[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    //重复调用encodeObject:forKey:方法归档所有需要归档的对象
    [arch encodeObject:dict forKey:@"myDict"];
    [arch encodeObject:set forKey:@"set"];
    [arch encodeObject:apple forKey:@"myApp"];
    //结束归档
    [arch finishEncoding];
    //程序将nsdata缓存区保存的数据写入文件
    if ([data writeToFile:@"multi.archive" atomically:YES]==NO) {
      NSLog(@"归档失败!");
    }
    //反序列化(反归档)
    
    NSData* data1=[NSData dataWithContentsOfFile:@"multi.archive"];
    //以NSData对象最为参数,创建nskeyedUnarchiver对象
    NSKeyedUnarchiver* unarch=[[NSKeyedUnarchiver alloc]initForReadingWithData:data1];
    //重复调用decodeObjectForKey:方法恢复所有需要恢复的对象
    NSDictionary* dict1=[unarch decodeObjectForKey:@"myDict"];
    NSSet* set1=[unarch decodeObjectForKey:@"set"];
    Apple* App1=[unarch decodeObjectForKey:@"myApp"];
    [unarch finishDecoding];
    
    //下面代码验证恢复是否成功
    NSLog(@"%@",dict1);
    NSLog(@"%@",set1);
    NSLog(@"%@",App1);
  }
}

输出:
2020-05-26 10:25:10.125416+0800 EX003[903:39115] {
“Object-c” = 89;
Perl = 109;
Python = 75;
Ruby = 69;
}
2020-05-26 10:25:10.125729+0800 EX003[903:39115] {(
“\U75af\U72c2Ajax\U8bb2\U4e49”,
“\U75af\U72c2IOS\U8bb2\U4e49”,
“\U75af\U72c2Android\U8bb2\U4e49”,
“\U75af\U72c2XML\U8bb2\U4e49”
)}
2020-05-26 10:25:10.125796+0800 EX003[903:39115] <Apple【_color=红色,_weight=3.4,_size=20】>
Program ended with exit code: 0

15.使用归档实现深复制

归档实际就是一个复制的过程,对象–>文档–>对象

#import <Foundation/Foundation.h>
@interface Apple:NSObject<NSCoding>
@property(nonatomic,copy)NSString* color;
@property(nonatomic,assign)double weight;
@property(nonatomic,assign)int size;
-(id)initWithColor:(NSString *)color weight:(double)weight size:(int)size;
@end

@implementation Apple

-(id)initWithColor:(NSString *)color weight:(double)weight size:(int)size{
  if (self=[super init]) {
    self.color=color;
    self.weight=weight;
    self.size=size;
  }
  return self;
}

//重写父类的desription方法
-(NSString*)description{
  //返回一个字符串
  return [NSString stringWithFormat:@"<Apple【_color=%@,_weight=%g,_size=%d】>",self.color,self.weight,self.size];
}

-(void)encodeWithCoder:(NSCoder *)coder{
  //调用NSCoder的方法归档该对象的每一个成员变量
  [coder encodeObject:_color forKey:@"color"];
  [coder encodeDouble:_weight forKey:@"weight"];
  [coder encodeInt:_size forKey:@"size"];
}

-(id)initWithCoder:(NSCoder*)coder{
  //使用NScoder依次恢复color,weight,size这3个key
  //所对应的value,并将恢复的value赋给当前对象的3个成员变量
  _color=[coder decodeObjectForKey:@"color"];
  _weight=[coder decodeDoubleForKey:@"weight"];
  _size=[coder decodeIntForKey:@"size"];
  return self;
}

@end
int main(int argc, const char * argv[]) {
  @autoreleasepool {
   //创建一个字典
    NSDictionary* dict=@{
      @"One":[[Apple alloc]initWithColor:@"红色" weight:3.4 size:20],
      @"Two":[[Apple alloc]initWithColor:@"绿色" weight:2.9 size:50]
    };
   
    //归档对象,将归档对象的数据写入NSData中
    NSData *data=[NSKeyedArchiver archivedDataWithRootObject:dict];
    //从NSData对象中恢复对象,这样既可完成深复制
    //上面只是进行了归档,而没有将归档对象写入文件。因为不需要,直接在内存与缓存之间交换数据既可
    NSDictionary* dictCopy=[NSKeyedUnarchiver unarchiveObjectWithData:data];
    //获取复制的dictionary对象中key为one所对应的Apple对象
    Apple* app= dictCopy[@"One"];
    //修改对象的color
    app.color=@"紫色";
    //访问复制对象的颜色值,应该输出紫色
    NSLog(@"dict复制对象中key为one对应苹果的颜色为:%@",app.color);
    //获取原始dictionary对象中的key为one所对应的apple对象
    Apple* app1=dict[@"One"];
    //访问原始对象的颜色值,应该输出红色
    NSLog(@"dict中key为one对应苹果的颜色为:%@",app1.color);
  }
  
}

输出:
2020-05-26 10:46:22.829709+0800 EX003[982:47751] dict复制对象中key为one对应苹果的颜色为:紫色
2020-05-26 10:46:22.830011+0800 EX003[982:47751] dict中key为one对应苹果的颜色为:红色

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值