博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MVC,KVO,KVC的简单认识
阅读量:5239 次
发布时间:2019-06-14

本文共 8342 字,大约阅读时间需要 27 分钟。

现在把分散的几个做一个总结

 

MVC(Model-View-Controller)中的M是模型对象,,主要负责存储数据,与用户界面无关,

模型对象通常会使用NSArray,NSDictionary,NSSet和数值类型NSString,NSDate,NSNumber

视图对象主要是一些UIButton,UILabel等

控制器对象负责保持视图对象和模型对象的一致性,控制应用的流程,并将模型对象保存至文件系统, 比如说UITableView对象中的数据更新了,控制器负责刷新数据,然后通知视图对象并显示。   

 

KVO KVC

下面转载自

 

对kvo/kvc做了简单的介绍,可作为入门读物。

有些术语描述不够精确请指正。

欢迎讨论。

Kvo是Cocoa的一个重要机制,他提供了观察某一属性变化的方法,极大的简化了代码。这种观察-被观察模型适用于这样的情况,比方说根据A(数据类)的某个属性值变化,B(view类)中的某个属性做出相应变化。对于推崇MVC的cocoa而言,kvo应用的地方非常广泛。(这样的机制听起来类似Notification,但是notification是需要一个发送notification的对象,一般是notificationCenter,来通知观察者。而kvo是直接通知到观察对象。)

适用kvo时,通常遵循如下流程:

1 注册:

 
-
(
void
)addObserver:(NSObject
*
)anObserver forKeyPath:(NSString
*
)keyPath options:(NSKeyValueObservingOptions)options context:(
void
*
)context

keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void型)

2 实现变化方法:

 
-
(
void
) observeValueForKeyPath:(NSString
*
)keyPath ofObject:(id)
object
change:(NSDictionary
*
)change context:(
void
*
)context

change里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时context不为空,这里context就能接收到。

是不是很简单?kvo的逻辑非常清晰,实现步骤简单。

说了这么多,大家都要跃跃欲试了吧。可是,在此之前,我们还需要了解KVC机制。其实,知道了kvo的逻辑只是帮助你理解而已,要真正掌握的,不在于kvo的实现步骤是什么,而在于KVC,因为只有符合KVC标准的对象才能使用kvo(强烈推荐要使用kvo的人先理解KVC)。

KVC是一种间接访问对象属性(用字符串表征)的机制,而不是直接调用对象的accessor方法或是直接访问成员对象。

key就是确定对象某个值的字符串,它通常和accessor方法或是变量同名,并且必须以小写字母开头。Key path就是以“.”分隔的key,因为属性值也能包含属性。比如我们可以person这样的key,也可以有key.gender这样的key path。

获取属性值时可以通过valueForKey:的方法,设置属性值用setValue:forKey:。与此同时,KVC还对未定义的属性值定义了valueForUndefinedKey:,你可以重载以获取你要的实现(补充下,KVC定义载NSKeyValueCoding的非正式协议里)。

在O-C 2.0引入了property,我们也可以通过.运算符来访问属性。下面直接看个例子:

 
@property NSInteger number;
instance.number
=
3
;
[instance setValue:[NSNumber numberWithInteger:
3
] forKey:
@"
number
"
];

注意KVC中的value都必须是对象。

以上介绍了通过KVC来获取/设置属性,接下来要说明下实现KVC的访问器方法(accessor method)。Apple给出的惯例通常是:

-key:,以及setKey:(使用的name convention和setter/getter命名一致)。对于未定义的属性可以用setNilValueForKey:。

至此,KVC的基本概念你应该已经掌握了。之所以是基本,因为只涉及到了单值情况,kvc还可以运用到对多关系,这里就不说了,留给各位自我学习的空间

接下来,我们要以集合为例,来对掌握的KVC进行一下实践。

之所以选择array,因为在ios中,array往往做为tableview的数据源,有这样的一种情况:

 假设我们已经有N条数据,在进行了某个操作后,有在原先的数据后多了2条记录;或者对N中的某些数据进行更新替换。不使用KVC我们可以使用reloadData方法或reloadRowsAtIndexPaths。前一种的弊端在于如果N很大消耗就很大。试想你只添加了几条数据却要重载之前N数据。后一种方法的不足在于代码会很冗余,你要一次计算各个indexPath再去reload,而且还要提前想好究竟在哪些情况下会引起数据更新,

倘若使用了KVC/kvo,这样的麻烦就迎刃而解了,你将不用关心追加或是更新多少条数据。

下面将以添加数据为例,说明需要实现的方法:

实现insertObject:inKeyAtIndex:或者insertKey:atIndexes。同时在kvo中我们可以通过change这个dictionary得知发生了哪种变化,从而进行相应的处理。

 

MVCS就是多了一个存储(S)

很多应用都会用到外部的数据,如web服务,数据库,文件系统,定位硬件,和相机等。只要是内存中的数据都可以称为外部数据。

处理外部数据, 用MVCS模式比MVC模式好。当然这只是其中一点,还有很多其他的

 

 

随时更新

 最下面将会举例说明

 

 

 

 

 

 

 -------------------------------------------------------------------

9.10转载自http://blog.csdn.net/crayondeng/article/details/9372433

键值观察:值更改时通知观察者

键值观察(Key-value observing,或简称 KVO)允许对象观察另一个对象的属性。该属性值改变时,会通知观察对象。它了解新值以及旧值;如果观察的属性为对多的关系(例如数组),它也要了解哪个 包含的对象发生了改变。KVO 有助于使应用程序变得更内聚,保持模型、控制器和视图层中的对象与改变同步。

与 NSNotificationCenter 通知相似,多个 KVO 观察者可以观察单一属性。此外,KVO 更动态,因为它允许对象观察任意属性,而不需任何新的 API,例如通知名称。KVO 是一个轻量级点对点通信机制,不允许观察所有实例的特定属性。

----以上解释来着官方文档----

Key-Value Observing机制的概述

Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者。

KVO的优点

当有属性改变,KVO会提供自动的消息通知。这样的 架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO机制提供的最大的优点。因为这个方案已经被明确定 义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可以在工程里使用。其次,KVO的架构非常的强大, 可以很容易的支持多个观察者观察同一个属性,以及相关的值。

KVO如何工作

需要三个步骤来建立一个属性的观察员。理解这三个步骤就可以知道KVO如何设计工作的。

 

(1)首先,构思一下如下实现KVO是否有必要。比如,一个对象,当另一个对象的特定属性改变的时候,需要被通知到。

例如,PersonObject希望能够觉察到BankObject对象的accountBalance属性的任何变化。

(2)那么PersonObject必须发送一个“”消息,注册成为BankObject的accountBalance属性的观察者。

(说明:“addObserver:forKeyPath:options:context:”方法在指定对象实例之间建立了一个连接。注意,这个连接不是两个类之间建立的,而是两个对象实例之间建立的。)

 

(3)为了能够响应消息,观察者必须实现“”方法。这个方法实现如何响应变化的消息。在这个方法里面我们可以跟自己的情况,去实现应对被观察对象属性变动的相应逻辑。

(4)假如遵循KVO规则的话,当被观察的属性改变的话,方法“observeValueForKeyPath:ofObject:change:context:”会自动被调用。

KVO是Cocoa的一个重要机制,他提供了观察某一属性变化的方法,极大的简化了代码。这种观察-被观察模型适用于这样的情况,比方说根据A(数据类) 的某个属性值变化,B(view类)中的某个属性做出相应变化。对于推崇MVC的cocoa而言,kvo应用的地方非常广泛。

适用kvo时,通常遵循如下流程:

1 注册:

-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context

keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void型)

2 实现变化方法:

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)objectchange:(NSDictionary *)change context:(void *)context

change里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时context不为空,这里context就能接收到。

是不是很简单?kvo的逻辑非常清晰,实现步骤简单。

说 了这么多,大家都要跃跃欲试了吧。可是,在此之前,我们还需要了解KVC机制。其实,知道了kvo的逻辑只是帮助你理解而已,要真正掌握的,不在于kvo 的实现步骤是什么,而在于KVC,因为只有符合KVC标准的对象才能使用kvo(强烈推荐要使用kvo的人先理解KVC)。

KVC--Key - value coding 机制

KVC是一种间接访问对象属性(用字符串表征)的机制,而不是直接调用对象的accessor方法或是直接访问成员对象。

key就是确定对象某个值的字符串,它通常和accessor方法或是变量同名,并且必须以小写字母开头。

Key path就是以“.”分隔的key,property can be object whick also contains property。比如我们可以person这样的key,也可以有key.gender这样的key path。

(setValue:forKey,valueForKey:)、(setValue:forKeyPath,valueForKeyPath:

获 取属性值时可以通过valueForKey:的方法,设置属性值用setValue:forKey:。与此同时,KVC还对未定义的属性值定义了 valueForUndefinedKey:,你可以重载以获取你要的实现(补充下,KVC定义载NSKeyValueCoding的非正式协议里)。

在O-C 2.0引入了property,我们也可以通过 .(点)运算符来访问属性。下面直接看个例子:

@property NSInteger number;
instance.number 
=
3
;
[instance setValue:[NSNumber numberWithInteger:
3
] forKey:
@"
number
"
];

注意KVC中的value都必须是对象。

下面举个例子解释一下KVC:

1.先定义两数据模型,下面的这两个model是无法直接访问属性的。

[cpp]
  1. @interface BookData : NSObject {  
  2.     NSString * bookName;  
  3.     float price;  
  4.     AuthorData * author;  
  5. }  
  6. @end  
  7. @implementation BookData  
  8. @end  
[cpp]
  1. @interface AuthorData : NSObject {  
  2.     NSString * name;  
  3. }  
  4. @end  
  5. @implementation AuthorData  
  6. @end  
使用KVC

[cpp]
  1. AuthorData * author1 = [[AuthorData alloc] init];  
  2. [author1 setValue:@"tom" forKey:@"name"];  
  3. BookData * book1 = [[BookData alloc] init];  
  4. [book1 setValue:@"english" forKey:@"bookName"];  
  5. [book1 setValue:@"20.0" forKey:@"price"];  
  6. [book1 setValue:author1 forKey:@"author"];  
  7.   
  8. NSLog(@"value=%@",[book1 valueForKey:@"bookName"]);  
  9. NSLog(@"price=%f",[[book1 valueForKey:@"price"] floatValue]);  
  10. NSLog(@"author=%@",[book1 valueForKeyPath:@"author.name"]);  
下面举一个例子解释一下 KVO

Person.h

[cpp]
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Person : NSObject  
  4.   
  5. @property(nonatomic,retain)NSString *name;  
  6. @property(nonatomic,assign)NSInteger age;  
  7.   
  8. -(void)changeName;  
  9.   
  10. @end  

Person.m

[cpp]
  1. #import "Person.h"  
  2.   
  3. @implementation Person  
  4.   
  5. @synthesize name,age;//属性name将被监视  
  6.   
  7. -(void)changeName  
  8. {  
  9.     name=@"changeName directly";  
  10. }  
  11.   
  12. @end  

PersonMonitor.h

[cpp]
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface PersonMonitor : NSObject  
  4.   
  5. @end  

PersonMonitor.m

[cpp]
  1. #import "PersonMonitor.h"  
  2.   
  3. @implementation PersonMonitor  
  4.   
  5.   
  6. //观察者需要实现的方法  
  7. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context  
  8. {  
  9.     if([keyPath isEqual:@"name"])  
  10.     {  
  11.         NSLog(@"change happen,old:%@ ,new:%@;context = %@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey],context);  
  12.     }  
  13. }  
  14.   
  15. @end  

main.m

[cpp]
  1. #import <Foundation/Foundation.h>  
  2. #import "Person.h"  
  3. #import "PersonMonitor.h"  
  4.   
  5. int main(int argc, const char * argv[])  
  6. {  
  7.   
  8.     @autoreleasepool {  
  9.           
  10.         //测试代码  
  11.         //监视对象  
  12.         Person *p =[[Person alloc] init];  
  13.   
  14.         //观察者对象  
  15.         PersonMonitor *pm= [[PersonMonitor alloc]init];  
  16.           
  17.         //Observer KVO收到通知指定的关键路径相对于接收器。  
  18.         /* 
  19.          *pm 对象注册KVO通知。观察者必须实现键值观察方法observeValueForKeyPath。 
  20.          *forKeyPath 关键路径,相对于接收器,用于观察的属性。这个值不能为零。 
  21.          *options NSKeyValueObservingOptions的组合值,指定包含在观察通知的内容。 
  22.          *context 任意的数据传递给anObserver在observeValueForKeyPath。 
  23.          */  
  24.           
  25.         [p addObserver:pm forKeyPath:@"name" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) context:@"hello world"];  
  26.           
  27.         //测试前的数据  
  28.         NSLog(@"p.name is %@",p.name);  
  29.           
  30.         //通过setvalue 的方法,PersonMonitor的监视将被调用  
  31.         [p setValue:@"name kvc" forKey:@"name"];  
  32.           
  33.         //查看设置后的值  
  34.         NSLog(@"p.name is %@",[p valueForKey:@"name"]);  
  35.           
  36.         //效果和通过setValue 是一致的  
  37.         p.name=@"name change by .name";  
  38.           
  39.         //通过person自己的函数来更改 name  
  40.         [p changeName];   
  41.         //最后一次修改是直接修改,所以没法产生通知。只有当我们调用KVC去访问key值的时候KVO才会起作用  
  42.         NSLog(@"p.name is %@",p.name);  
  43.   
  44.         //删除观察者  
  45. //        [p removeObserver:pm forKeyPath:@"name"];  
  46.           
  47.         }  
  48.     return 0;  
  49. }  
终端输出结果:

2013-07-19 11:04:17.946 KVC_KVOTest[1187:303] p.name is (null)

2013-07-19 11:04:17.948 KVC_KVOTest[1187:303] change happen,old:<null> ,new:name kvc;context = hello world

2013-07-19 11:04:17.949 KVC_KVOTest[1187:303] p.name is name kvc

2013-07-19 11:04:17.949 KVC_KVOTest[1187:303] change happen,old:name kvc ,new:name change by .name;context = hello world

2013-07-19 11:04:17.950 KVC_KVOTest[1187:303] p.name is changeName directly

刚接触KVO  KVC 所以只是懂了个大概,以后还是要通过实践应用才更深入的理解。

注明:以上内容基本上参考了其他博友的文章和例子,这里整合了。大笑

 

转载于:https://www.cnblogs.com/ioschen/p/3295470.html

你可能感兴趣的文章
微服务实践:服务运维
查看>>
最小的K个数(python)
查看>>
创建一个项目并在GitHub上发出拉取请求
查看>>
省选专练之容斥【BZOJ4767】两双手
查看>>
01矩阵
查看>>
动态ip发布web+绑定域名
查看>>
点云的一些疑问
查看>>
PHP面向对象的基本写法(区别于java)
查看>>
【Static Program Analysis - Chapter 3】Type Analysis
查看>>
第4次作业类测试代码+163+张玉洁
查看>>
Linux磁盘管理及LVM讲解
查看>>
SQL Server 2008数据类型
查看>>
Linux服务器注意事项
查看>>
vs2010 项目生成成功,发布失败
查看>>
把文件保存到 sdcard
查看>>
大数据时代下的企业管理创新
查看>>
ES6数组
查看>>
洛谷 [P2051] 中国象棋
查看>>
『题解』UVa11324 The Largest Clique
查看>>
iPhone深入浅出 iOS 之生命周期
查看>>