高级UIKit-04(NSUserDefaults、NSKeyedArchiver、对象归档方法)
【day05_1_UserDefault】:判断应用程序是否是第一次运行
NSUserDefaults:用来保存应用程序的配置信息如:程序运行次数,用户登陆信息等。
// 使用系统提供的NSUserDefaults对象判断
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
int runCount = [[userDefaults objectForKey:@"runCount"] intValue];
if (runCount == 0) {
NSLog(@"第一次运行!!!");
}
runCount++;
[userDefaults setObject:[NSNumber numberWithInt:runCount] forKey:@"runCount"];
[userDefaults synchronize]; // 同步
练习:三个界面ABC,运行次数奇数次进C,偶数次进B
在MXAppDelegate.m中写
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 因为那个箭头可以直接确定谁是rootViewController,所以可以简化代码
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
int runCount = [[userDefaults objectForKey:@"runCount"] intValue];
if (runCount % 2 == 0) {
UIViewController *bVC = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"bVC"];
[self.window.rootViewController presentViewController:bVC animated:YES completion:nil];
self.window.rootViewController = bVC;
}
runCount++;
[userDefaults setObject:[NSNumber numberWithInt:runCount] forKey:@"runCount"];
[userDefaults synchronize]; // 同步
return YES;
}
【day05_2_ArrayArchiver】:数组归档的使用
归档的使用:把对象转成二进制NSData,可以进行保存或网络传输
如何实现归档:需要让对象实现NSCoding协议
已经实现了NSCoding协议的对象有:数组和字典
数组归档:
// 数组归档
NSArray *namesArray = @[@"张三",@"李四",@"王五"];
// 1.创建可变的data对象,装数据
NSMutableData *data = [NSMutableData data];
// 2.创建归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 3.把对象编码
[archiver encodeObject:namesArray forKey:@"names"];
// 4.编码完成
[archiver finishEncoding];
// 5.保存归档
[data writeToFile:@"/Users/tarena/Desktop/namesArchiver" atomically:YES];
数组反归档:
// 数组反归档
// 1.得到data
NSData *data = [NSData dataWithContentsOfFile:@"/Users/tarena/Desktop/namesArchiver"];
// 2.创建反归档对象
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
// 3.解码并存到数组中
NSArray *namesArray = [unArchiver decodeObjectForKey:@"names"];
// 4.循环打印
for (NSString *name in namesArray) {
NSLog(@"%@",name);
}
【day05_3_DictionaryArchiver】字典的归档反归档和数组一样。
【day05_4_AddStringToArchiver】:添加输入框内容到textView中,关闭程序后textView中内容还在,(让UITextView不可编辑,勾掉Editable)
这个使用到归档,代码:
// 加载数组归档数据
-(void)loadInfo{
// 从归档中取数据
// 数组反归档
self.namesTextView.text = @"";
NSData *nameData = [NSData dataWithContentsOfFile:@"/Users/tarena/Desktop/nameArrayArchiver"]; // 得到data
NSKeyedUnarchiver *unarc = [[NSKeyedUnarchiver alloc] initForReadingWithData:nameData]; // 创建反归档对象
self.nameArray = [unarc decodeObjectForKey:@"names"]; // 解码
for (NSString *name in self.nameArray) { // 取出数组中数据拼接到textView
self.namesTextView.text = [self.namesTextView.text stringByAppendingFormat:@"%@\n",name];
}
}
// 添加姓名
- (IBAction)addNameToTextView:(id)sender {
NSString *name = self.nameTextField.text; // 取出输入的字符串
NSMutableArray *mutableNameArray = [NSMutableArray arrayWithArray:self.nameArray]; // 把不可变数组变为可变数组
[mutableNameArray addObject:name]; // 添加字符串到数组中
// 数组归档
NSMutableData *nameData = [NSMutableData data]; // 创建可变data对象
NSKeyedArchiver *arc = [[NSKeyedArchiver alloc] initForWritingWithMutableData:nameData]; // 创建归档对象
[arc encodeObject:mutableNameArray forKey:@"names"]; // 给数组编码
[arc finishEncoding]; // 编码完成
[nameData writeToFile:@"/Users/tarena/Desktop/nameArrayArchiver" atomically:YES]; // 保存到指定的路径
[self loadInfo];
}
总结:反归档如果返回数组,一般用NSArray接收,如果在程序中要改变NSArray的值,要先把它转成可变数组,然后把这个新数组重新归档。
注意归档时,要创建可变的NSData对象。
【day05_5_ArchiverPerson】:对象可以归档反归档必须做的事
1.遵守NSCoding协议
2.实现该协议的两个方法
代码如下:
// 属性编码
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
// 属性解码
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
【day05_6_PersonsArchiver】:人员名单,功能有添加人员,删除人员,修改人员。使用归档。
添加:
添加时要跳转到新的界面,一般这么做:
1.如果第一个界面用navigation包含了就把整个界面push到第二个界面,使用viewController连接。
2.然后设置该连线也就是segue的identifier值。
3.然后第一个界面中的控件或是tableView的cell通过一个方法[selfperformSegueWithIdentifier:@"personInfoVC"sender:person];进行segue跳转并可以传值。
4.在segue跳转前还有一个方法可以把传的值赋给要跳转的界面,就是- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
在添加界面中首先把归档的数据取出来添加进去,然后把新的数据重新归档。
添加代码如下:
// 添加数据
- (IBAction)addOrEditButtonAction:(id)sender {
// 添加
MXPerson *person = [[MXPerson alloc] init];
person.name = self.nameTextField.text;
person.age = [self.ageTextField.text intValue];
// 首先需要取出归档数据,在往里添加
NSData *data = [NSData dataWithContentsOfFile:@"/Users/tarena/Desktop/persons"];
NSKeyedUnarchiver *unarc = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSArray *oldPersonArray = [unarc decodeObjectForKey:@"persons"];
NSMutableArray *newPersonArray = [NSMutableArray arrayWithArray:oldPersonArray];
[newPersonArray addObject:person]; // 添加数据
// 把对象归档
NSMutableData *personData = [NSMutableData data];
NSKeyedArchiver *arc = [[NSKeyedArchiver alloc] initForWritingWithMutableData:personData];
[arc encodeObject:newPersonArray forKey:@"persons"];
[arc finishEncoding];
[personData writeToFile:@"/Users/tarena/Desktop/persons" atomically:YES];
[self.navigationController popViewControllerAnimated:YES];
}
修改:
点击cell后跳到修改界面,然后点击按钮修改。
在跳转时要把当前cell(也就是数组中的某个元素)的数据传到修改界面并显示,修改数据后重新归档。
因为在修改界面要用到第一个界面中数组数据,所以在跳转到修改界面前把自己赋给修改界面的delegate(该代理的类型就是第一个界面),然后进行修改并重新归档。
注意:在跳转时会有多个sender值,在跳转界面要做判断。本例中点击添加,传的sender是nil,点击cell传的sender就是该cell数据。
代码如下:
// 点击cell后跳转到修改界面并传cell的数据
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
MXPerson *person = self.personArray[indexPath.row];
[self performSegueWithIdentifier:@"personInfoVC" sender:person];
}
// segue跳转前把数据赋给修改界面
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
MXViewController *personInfoVC = segue.destinationViewController;
personInfoVC.person = sender;
personInfoVC.delegate = self;
}
// 添加或修改数据
- (IBAction)addOrEditButtonAction:(id)sender {
if (self.person) { // 修改
self.person.name = self.nameTextField.text;
self.person.age = [self.ageTextField.text intValue];
[self.delegate savePerson];
} else{ // 添加
}
[self.navigationController popViewControllerAnimated:YES];
}
删除:
从归档中删除,然后保存归档
代码如下:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.personArray removeObjectAtIndex:indexPath.row]; // 从归档中删除
[self savePerson]; // 保存归档
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
高级UIKit-04(NSUserDefaults、NSKeyedArchiver、对象归档方法)的更多相关文章
- iOS文档序列化(对象归档)
对象归档: 概念: 对象归档是指将对象写入文件保存在硬盘,当再次又一次打开程序时,能够还原这些对象.也称:对象序列化.对象持久化. 数据持久性的方式(事实上就是3类) 1,NSKeyedArchive ...
- iOS数据存储之对象归档
iOS数据存储之对象归档 对象归档 对象归档是iOS中数据持久化的一种方式. 归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文 ...
- iOS 数据持久化(1):属性列表与对象归档
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...
- 读写应用程序数据-NSUserDefault、对象归档(NSKeyedArchiver)、文件操作
ios中数据持久化存储方式一般有5种:NSUserDefault.对象归档(NSKeyedArchiver).文件操作.数据库存储(SQLite3).CoreData. 1.NSUserDefault ...
- Python的高级特性8:你真的了解类,对象,实例,方法吗
Python的高级特性1-7系列是本人从Python2过渡3时写下的一些个人见解(不敢说一定对),接下来的系列主要会以类级为主. 类,对象,实例,方法是几个面向对象的几个基本概念,其实我觉得很多人并不 ...
- jvm高级特性(2)(判断存活对象算法,finaliza(),方法区回收)
JVM高级特性与实践(二):对象存活判定算法(引用) 与 回收 垃圾回收器GC(Garbage Collection) 于1960年诞生在MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语 ...
- 06JS高级创建对象使用原型共享对象方法
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- JS高级——扩展内置对象的方法
基本概念 内置对象有很多,几个比较重要的:Math.String.Date.Array 基本使用 1.内置对象创建出来的对象使用的方法使用的其实都是内置对象的原型对象中的方法 (1)a并没有charA ...
- iOS开发——UI进阶篇(十一)应用沙盒,归档,解档,偏好设置,plist存储,NSData,自定义对象归档解档
1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每 ...
随机推荐
- OFbiz--HelloWorld
上篇博客<OFbiz--简单介绍>我们介绍了OFbiz是什么,以下我们就開始用OFbiz开发我们的第一个程序--HelloWorld. 过程例如以下: 首先在hot-deploy下新建文件 ...
- java 构造函数是如何执行的
1.构造函数不是方法!! 原因1:方法的话,会直接执行方法体内的代码,但是构造函数首先执行的不是{}里的代码块,而是给对象的成员初始化: 2.方法可以被调用其他方法调用,但是构造函数不能被方法或变量调 ...
- 行列转换小结 Pivot ,Unpivot (转,改)
行专列 Pivot 1)SQL 2000版本 静态 SELECT ID , SUM(CASE Code WHEN 'Item1' THEN Value END) AS Item1 , SUM(CASE ...
- iOS开发之第三方登录微博-- 史上最全最新第三方登录微博方式实现
相关资源地址: 本项目demo地址 : https://github.com/zhonggaorong/weiboSDKDemo 最新SDK下载: 最新微博SDK 官网注册地址:点击打开链接 最新 ...
- 基于hash的文档判重——simhash
本文环境: python3.5 ubuntu 16.04 第三方库: jieba 文件寄于github: https://github.com/w392807287/angelo_tools.git ...
- Map 的遍历
一.Map的遍历 在后面java的开发过程中会遇到Map类的使用,然而map的遍历是一大问题. Map遍历用两种比较交代的方法: package edu.map; import java.util.H ...
- python collections.Counter笔记
Counter是dict的子类,所以它其实也是字典.只不过它的键对应的值都是计数,值可以是任意整数.下面是四种创建Counter实例的例子: >>> c = Counter() # ...
- 数组排序-Objectivec
发表于昨天(23:33)(2013-11-03 23:33) ,已有15次阅读 ,共0个评论 摘要: 总结OC中数组排序3种方法:sortedArrayUsingSelector:;sortedArr ...
- 配置php网页显示错误
发现问题比解决问题重要,使用php集成开发环境Appserv网页会提示各种语法错误,但自己配置开发环境无法提示错误,特别当不是语法错误,比如com组件的调用,当不知道问题出现在何处,是不能忍受的,这时 ...
- 64位CentOS上编译 Hadoop 2.2.0
下载了Hadoop预编译好的二进制包,hadoop-2.2.0.tar.gz,启动起来后.总是出现这样的警告: WARN util.NativeCodeLoader: Unable to load n ...