数据存储

1.1.3.使用通知传值

1.2.Segue使用

2. KVC&&KVO2.1.什么是KVC

KVC - Key Value Coding键值(路径)编码KVC是一种间接修改/读取对象属性的一种方式KVC被称为苹果开发的大招!

KVC在使用时,需要注意,键值名称在对象属性中必须存在,否则会崩溃!

2.2.什么是KVO

Key Value Observer键值观察(观察者模式)

通知中心同样也是观察者模式

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......2.3.KVC设置值

2.3.1.给字符串属性 和 数值属性赋值

Person*p = [[Personalloc]init];//使KVC来给对象赋值

[psetValue:@"李四"forKeyPath:@"name"];

//给数值型属性赋值时,同样可以使 字符串[psetValue:@"18"forKeyPath:@"age"];

2.3.2.给对象属性赋值

Student*stu = [[Studentalloc]init];

[stusetValue:@"李四"forKeyPath:@"name"];

[stusetValue:@"18"forKeyPath:@"age"];

[stusetValue:@"20"forKeyPath:@"number"];Book*book = [[Bookalloc]init];

stu.book= book;

//使KVC给Book赋值

[stusetValue:@"iPhone"forKeyPath:@"book.bookName"];

2.4.KVC取值

Student*stu = [[Studentalloc]init];

[stusetValue:@"lisi"forKeyPath:@"name"];

[stusetValue:@"18"forKeyPath:@"age"];

[stusetValue:@"20"forKeyPath:@"number"];

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......

Book*book = [[Bookalloc]init];

stu.book= book;

[stusetValue:@"iPhone"forKeyPath:@"book.bookName"];

Student*stu1 = [[Studentalloc]init];

[stu1setValue:@"wangwu"forKeyPath:@"name"];

[stu1setValue:@"18"forKeyPath:@"age"];

[stu1setValue:@"20"forKeyPath:@"number"];Book*book1 = [[Bookalloc]init];

stu1.book= book1;

[stu1setValue:@"ios"forKeyPath:@"book.bookName"];

NSArray*students =@[stu,stu1];//需求,将两个学 的姓名 成 个数组

//普通做法

//

//

//

//

//

//

//

//

NSMutableArray *arrayM = [NSMutableArray array];

for (Student *stu in students) {

[arrayM addObject:stu.name];

}

NSLog(@"%@", arrayM);

KVC取值

使KVC取值的时候,如果当前对象不包含指定的键值

那么KVC会进 对象内部,继续搜索!

NSLog(@"%@", [studentsvalueForKeyPath:@"name"]);NSLog(@"%@", [studentsvalueForKeyPath:@"book.bookName"]);

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......2.5.KVO的使用

2.5.1.设置监听

Student *stu = [[Student alloc] init];

stu.name =@"wangwu";

stu.age =16;

stu.number =20;

Book *book = [[Book alloc] init];

book.bookName =@"ios";

stu.book = book;self.student =stu;

//谁来监听 监听谁

//观察student的属性变化

// 1> self负责监听的对象

通知中 负责

NSNotificationCenter是由

// 2> keyPath要观察的属性键值路径,KVO主要 于对模型属性变化进

观察的 种模式

//通知中 是通过对象POST字符串给通知中 来达到观察 的的

// 3>选项"|"(并且)位运算,可以同时 持多个选项

// 4>上下

[stu addObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionNew|NSKeyValueObservingO

ptionOld context:@"student"];

stu.name =@"lisi";

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......2.5.2.监听代理

//分类: 被称为:隐式代理,灵活度很 ,但是代码的可读性不好,不建议

使 !

//  delegate ->显式代理//

//观察监听 法,所有的监听事件发 时,都统 调 监听者的此 法!

//  1> keyPath

//  2> object

//  3> change

//  4> context

观察的键值路径

观察的对象

改变,新、旧数值发送过来

上下 ,建 观察时指定的上下 ,如果同时监听多个属

性,可以通过上下 加以区分

-(void)observeValueForKeyPath:(NSString*)keyPath

ofObject:(id)object change:(NSDictionary

*)change context:(void*)context{

NSLog(@"keyPath = %@ , object = %@ , change = %@ ,context

= %@", keyPath, object, change, context);

}

3. RGB颜色黑色是一点颜色都没有,白色包含了所有的颜色

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......4.数据存储

4.1.本质所有数据存储的本质都是做数据持久化,也就是写入文件

4.2.存储方式

NSUserDefaults存储

自定义文件存储Plist,txt,xml数据库存储sqlite

网络存储

3.应用之间通信和分享数据的机制http://blog.csdn.net/tenfyguo/article/details/9063675

4.3.沙盒介绍

沙盒路径是应用程序专门为用户存储数据而存在的目录** /Users/...../Data/...这个是沙盒路径。

** /Users/...../Bundle/....这个是Bundle路径。

而bundle路径是应用程序安装路径。

每个应用程序只能访问自己的沙盒路径。

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......4.4.沙盒目录结构

4.4.1. Documents目录:保存应用程序自己的数据(比如:游戏进度存档、软件的一些个人设置等)。通过iTunes、

iCloud备份时,会备份这个目录下的数据。

4.4.2. Tmp目录:

存储一些其他临时数据,系统磁盘空间不够,手机重启时,会自动清除这个目录的数

据。无需程序员手动清除该目录中的数据.iTunes、iCloud备份时,不会备份这个目录下的数

据。

4.4.3. Caches目录:

保存从网络上下载的文件(比如:听歌时的缓存、图片的缓存等),这个目录下的数据

不会被自动删除,需要程序员自己实现清除目录数据功能。iTunes、iCloud备份时,不会备

份这个目录下的数据。

4.4.4. Preference目录:

保存通过"偏好设置"写入的数据。iTunes、iCloud备份时,会备份这个目录下的数据。

4.5.沙盒路径

4.5.1.获取沙盒根目录-拼接方式

NSString *path = NSHomeDirectory();

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......4.5.2.路径拼接

path = [path stringByAppendingString:@”/Documents”];

path = [path stringByAppendingPathComponent:@”Documents”];

4.5.3.获取沙盒全路径-系统方式[NSSearchPathForDirectoriresInDomains() firstObject];

yes是绝对路径no是相对路径

NSSearchPathDomainMask

[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject];

NSUserDomainMask =1,//户主 录中NSLocalDomainMask =2,//当前机器中NSNetworkDomainMask =4,//络中可 的主机NSSystemDomainMask =8,//系统 录,不可修改(/System)NSAllDomainsMask =0x0ffff,//全部

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......4.6.文件读写

4.6.1. plist文件读写写入字典:

[dict writeToFile:path atomically:YES];

读取字典:

NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

缺点:

通过plist文件来保存数据,无法直接将一个对象保存到文件中。

4.7.偏好读写

本质就是通过plist文件存储数据

但是使用起来更简单(无需关注文件、文件夹路径和名称)。目录每次都会发生改变

通过"偏好设置"的 式读、写 件时,路径在"沙盒根 录"->"Library"->"Preferences"

数据只能存储在一个文件中,不存储大批量数据(很多时候大批量数据要分多个文件存储)

4.7.1.写入

NSUserDefaults*defaults = [NSUserDefaultsstandardUserDefaults];

[defaultssetObject:@"zhangsan"forKey:@"name"];

[defaultssetBool:YESforKey:@"sex"];

[defaultssetInteger:20forKey:@"age"];

[defaultssynchronize];

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......4.7.2.读出

NSUserDefaults*defaults = [NSUserDefaultsstandardUserDefaults];NSString*name = [defaultsobjectForKey:@"name"];BOOLsex = [defaultsboolForKey:@"sex"];NSIntegerage = [defaultsintegerForKey:@"age"];

4.7.3.缺点

通过"plist"文件来保存数据,无法直接将一个对象保存到文件中。比如Person对象就没有

writeToFile方法。而偏好设置只能存储少量数据,对于大数据存储不适合4.7.4.注意

使用对象:仅仅是Foundation框架中的一些类,比如:

NSString\NSArray\NSDictionary\NSSet\NSNumber\NSData,对于其它数据类型不能直接存

储。

5.数据归档5.1.特点

"归档"是一种可以把任何对象,直接保存为文件的方式。(其中包括"归档"与"反归档(读档)")

5.2.前提必须是实现协议

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......通过"归档"的方式来存储,对象必须遵守NSCoding协议,也就意味着通过"归档"的方式能

将任何遵守了NSCoding协议的"对象"存储到文件中

5.3.归档可以归档数组

重点:子类必须也要让父类归档。

5.4.反归档

重点:父类必须init,子类必须也要调用父类的反归档

6.完善登录业务6.1.偏好设置-写入

写入自动登录和记住密码状态

写入用户名密码

//户偏好数据写

- (void)userDefaultWrite

{

standardUserDefaults];//2.写 数据

BOOLisremerberPwd=self.rememberPwd.on;BOOLisAutoLogin=self.autoLogin.on;

//写  动登录和记住密码的属性值

[udsetBool:isremerberPwdforKey:@"isremerberPwd"];

//1.创建偏好写 对象

NSUserDefaults*ud=[NSUserDefaults

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

6.2.写入时间当登录成功时写入

6.3.自动登录

想要高薪就业?还等什么?照着文档不停的敲吧.......

[udsetBool:isAutoLoginforKey:@"isAutoLogin"];

//判断是否是记住密码,如果是就再写  户名和密码

if(isremerberPwd) {

[udsetObject:self.nameView.textforKey:@"name"];

[udsetObject:self.pwdView.textforKey:@"pwd"];

}

//3.同步

[udsynchronize];

}

[selfuserDefaultWrite];

//动登录功能

- (void)autoLoginAction{

//读取偏好

NSUserDefaults*ud=[NSUserDefaultsstandardUserDefaults];

BOOLisremerberPwd=[udboolForKey:@"isremerberPwd"];BOOLisAutoLogin=[udboolForKey:@"isAutoLogin"];

//赋值开关

[self.rememberPwdsetOn:isremerberPwdanimated:YES];

[self.autoLoginsetOn:isAutoLoginanimated:YES];

//判断是否是记住密码如果是就再填  户名和密码

if(isremerberPwd) {self.nameView.text=[udobjectForKey:@"name"];self.pwdView.text=[udobjectForKey:@"pwd"];

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......

}if(isAutoLogin) {

// [self login:nil];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,

(int64_t)(0.5*NSEC_PER_SEC)),dispatch_get_main_queue(),

^{

[selflogin:nil];

});

}

}

6.4.注意:在主队列启动登录

if(isAutoLogin) {//这样不能移除提 框

// [self login:nil];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,

(int64_t)(0.5*NSEC_PER_SEC)),dispatch_get_main_queue(),

^{

[selflogin:nil];

});

}

7.私人通讯录数据归档7.1.模型类

7.1.1.模型类-实现归档协议

@interfaceCZContact :NSObject

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......7.1.2.模型类-归档

//归档

- (void)encodeWithCoder:(NSCoder*)aCoder

{

[aCoderencodeObject:self.nameforKey:@"name"];

[aCoderencodeObject:self.phoneforKey:@"phone"];

}

7.1.3.模型类-反归档

//反归档

- (instancetype)initWithCoder:(NSCoder*)aDecoder

{

if(self=[superinit]) {self.name=[aDecoderdecodeObjectForKey:@"name"];self.phone=[aDecoderdecodeObjectForKey:@"phone"];

}

return self;

}

7.2.控制器7.2.1.数据归档

//对联系 数据进 归档存储

- (void) saveContact

{

NSString

*docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentD

irectory,NSUserDomainMask,YES)lastObject];

NSString*filePath=[docPathstringByAppendingPathComponent:@"contact.data"];

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......

//归档操作

[NSKeyedArchiverarchiveRootObject:self.contactstoFile:filePath];

}

7.2.2.数据归档位置—添加联系人

- (void) addBtnDidClick:(AddViewController*)vc

withContact:(CZContact*)contact{

//1.添加模型到数组

[self.contactsaddObject:contact];

//2.刷新表格

[self.tableViewreloadData];

//3.进 数据--归档

[selfsaveContact];

}

7.2.3.数据归档位置—修改联系人

- (void)editBtnDidClick:(EditViewController*)vc{//刷新tableView

// [self.tableView reloadData];

NSIndexPath*indexPath=self.tableView.indexPathForSelectedRow;

[self.tableViewreloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationFade];

//数据存储

[selfsaveContact];

}

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......7.3.数据源

源数据从归档文件中加载

//懒加载--从归档 件中获得数据

- (NSArray*)contacts

{

if(_contacts==nil) {NSString

*docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentD

irectory,NSUserDomainMask,YES)lastObject];

NSString*filePath=[docPathstringByAppendingPathComponent:@"contact.data"];

_contacts=[NSKeyedUnarchiverunarchiveObjectWithFile:filePath];

if(_contacts==nil)//有可能为nil{

_contacts=[NSMutableArrayarray];

}

}

return_contacts;

}

8.项目删除联系人8.1.tableViewCell左滑出现删除按钮

//实现此 法就可以实现cell的左边滑动出删除按钮了

- (void)tableView:(UITableView*)tableView

commitEditingStyle:(UITableViewCellEditingStyle)editingSt

yle forRowAtIndexPath:(NSIndexPath*)indexPath{

}

//确定删除按钮的 本

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

8.2.删除联系人操作

想要高薪就业?还等什么?照着文档不停的敲吧.......

- (NSString*)tableView:(UITableView*)tableView

titleForDeleteConfirmationButtonForRowAtIndexPath:(NSInde

xPath*)indexPath

{

return@"删除";

}

//实现此 法就可以实现cell的左边滑动出删除按钮了//只有删除状态才有删除按钮的显  和 点击删除按钮的回调操作

- (void)tableView:(UITableView*)tableView

commitEditingStyle:(UITableViewCellEditingStyle)editingSt

yle forRowAtIndexPath:(NSIndexPath*)indexPath{

//先删除数据源

[self.contactsremoveObjectAtIndex:indexPath.row];

//重新归档--就是删除归档 件中的已经删除的联系[selfsaveContact];

//再删除tableView中的显

[self.tableViewdeleteRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationFade];

}

//对联系 数据进 归档存储

- (void) saveContact

{

NSString

*docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentD

irectory,NSUserDomainMask,YES)lastObject];

NSString*filePath=[docPathstringByAppendingPathComponent:@"contact.data"];

//归档操作--归档数组  的所有对象,也就是说先删除 件中的所有对

传智播客致力打造专业的IT实战培训课程——务实、创新、质量、专注、分享、责任

想要高薪就业?还等什么?照着文档不停的敲吧.......

象,然后重新归档

[NSKeyedArchiverarchiveRootObject:self.contactstoFile:filePath];

}

9. QQ主流框架9.1.目的

这个案例主要是综合使用UITabBarController和UINavigationController.复习静态单元格的创建和使用

进一步的掌握多控制器的管理。

9.2.项目框架

注意:TableViewController:

Content : Static Cells

Style : Grouped

TableViewCell:

Style : Basic

Accessory : Disclosure Indicator

推荐阅读更多精彩内容