iOS开发——实用篇&KVO与KVC详解
KVO与KVC详解
由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby、Python的动态特性,例如动态类型、动态加载、动态绑定等。今天我们着重介绍ObjC中的键值编码(KVC)、键值监听(KVO)特性:
键值编码KVC
我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象。其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Value Coding(简称KVC)。
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:
- 动态设置: setValue:属性值 forKey:属性名(用于简单路径)、setValue:属性值 forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性,那么person.account就是一个复合属性)
- 动态读取: valueForKey:属性名 、valueForKeyPath:属性名(用于复合路径)
键值监听KVO
我们知道在WPF、Silverlight中都有一种双向绑定机制,如果数据模型修改了之后会立即反映到UI视图上,类似的还有如今比较流行的基于MVVM设计模式的前端框架,例如Knockout.js。其实在ObjC中原生就支持这种机制,它叫做Key Value Observing(简称KVO)。KVO其实是一种观察者模式,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器的视图组件就会被激发,激发时就会回调监听器自身。在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,不过幸运的是NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO。
在ObjC中使用KVO操作常用的方法如下:
- 注册指定Key路径的监听器: addObserver: forKeyPath: options: context:
- 删除指定Key路径的监听器: removeObserver: forKeyPath、removeObserver: forKeyPath: context:
- 回调监听: observeValueForKeyPath: ofObject: change: context:
KVO的使用步骤也比较简单:
- 通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
- 重写监听器的observeValueForKeyPath: ofObject: change: context:方法
/*********************************KVC/KVO*******************************************/
KVC
kvc在实际开发中使用最多的地方一般有两个
- 字典转模型:但是这个有一个局限性,如果他的属性也是一个模型的时候不能使用这个方法,或者不能一一对应的时候
- 通过属性键设置对应属性的值
字典转模型:
#pragma mark 简单字典转模型
NSDictionary *dict = @{
@"name" : @"jack",
@"money" : @"20.7",
};
[p setValuesForKeysWithDictionary:dict];
NSLog(@"name = %@, money = %f", p.name, p.money);
#pragma mark 复杂模型
NSDictionary *dict = @{
@"name" : @"jack",
@"money" : @"20.7",
@"dog" : @{
@"name" : @"wangcai",
@"price" : @"10.8"
},
@"books" : @[
@{
@"name" : @"5分钟突破iOS开发",
@"price" : @"19.8"
},
@{
@"name" : @"3分钟突破iOS开发",
@"price" : @"24.8"
},
@{
@"name" : @"1分钟突破iOS开发",
@"price" : @"29.8"
}
]
};
[p setValuesForKeysWithDictionary:dict];
NSLog(@"%@", p);
}
设置属性的值:
#pragma mark 单个值
p.name = @"lnj";
p.money = 99.8;
[p setValue:@"lnj" forKey:@"name"];
[p setValue:@(99.8) forKey:@"money"];
NSLog(@"name = %@, money = %f", p.name, p.money);
#pragma mark 多层赋值
p.dog = [XMGDog new];
p.dog.name = @"wangcai";
p.dog.price = ;
[p.dog setValue:@"wangcai" forKey:@"name"];
[p.dog setValue:@() forKey:@"price"];
[p setValue:@"wangcai" forKeyPath:@"dog.name"];
[p setValue:@() forKeyPath:@"dog.price"];
NSLog(@"name = %@, price = %f", p.dog.name, p.dog.price);
#pragma mark 私有属性
[p setValue:@"lnj" forKeyPath:@"_name"];
[p setValue:@() forKeyPath:@"_age"];
NSLog(@"name = %@", p.name);
[p say];
KVO
1:创建一个对象
iCocos *stu =
2:注册指定Key路径的监听器,并且修改相应的属性
[stu addObserver:self forKeyPath:@"score" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
stu.score = ;
stu.score = ;
3:删除指定Key路径的监听器
#warning 注意只有调用set方法修改才能监听到 \
内部实现原理是: 系统会自动给我们生成一个子类, 然后重写子类的set方法, 在set方法中通知监听
stu->_score = ;
[stu removeObserver:self forKeyPath:@"score"];
4:回调监听
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context
{
NSLog(@"keyPath = %@, obj = %@, change = %@, context = %@", keyPath, object, change, context);
}
KVO内部实现机制:
系统会自动给我们生成一个子类, 然后重写子类的set方法, 在set方法中通知监听
iOS开发——实用篇&KVO与KVC详解的更多相关文章
- iOS开发支付篇——内购(IAP)详解
1 <em>内购所需要的资料整理总结,史上最完整的,哈哈哈哈哈哈</em> 思维导图 重点总结: 1 2 3 4 5 6 7 8 9 10 11 12 13 1.获取内购列表( ...
- iOS开发——实用篇&提高iOS开发效率的方法和工具
提高iOS开发效率的方法和工具 介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时 ...
- iOS开发 - OC - block的详解 - 基础篇
深入理解oc中的block 苹果在Mac OS X10.6 和iOS 4之后引入了block语法.这一举动对于许多OC使用者的编码风格改变很大.就我本人而言,感觉block用起来还是很爽的,但一直以来 ...
- iOS 开发之 -- UDID和UUID的详解
老实说,搞了几年的ios开发了,对基础的概念,还是不牢固,整天都是为了赶进度而码代码,这里记录一下这两者的区别: UDID的全名为 Unique Device Identifier :设备唯一标识符. ...
- iOS开发——高级技术&本地化与国际化详解
本地化与国际化详解 效果如下: 英语: 中文: 具体实现如下: ...
- 【iOS 开发】基本 UI 控件详解 (UIButton | UITextField | UITextView | UISwitch)
博客地址 : http://blog.csdn.net/shulianghan/article/details/50051499 ; 一. UI 控件简介 1. UI 控件分类 UI 控件分类 : 活 ...
- iOS开发——实用篇Swift篇&项目开发常用实用技术
项目开发常用实用技术 实现拨打电话 要实现打电话功能,最简单最直接的方式便是:直接跳到拨号界面 (注意:这个需要真机调试,模拟器无效果) UIApplication.sharedApplica ...
- iOS开发 - OC - block的详解 - 深入篇
深入理解oc中的block 苹果在Mac OS X10.6 和iOS 4之后引入了block语法.这一举动对于许多OC使用者的编码风格改变很大.就我本人而言,感觉block用起来还是很爽的,但一直以来 ...
- iOS开发——实用篇Swift篇&QQ登入界面实现
QQ登入界面实现 我们知道在App Store中几乎所有软件都设计到账户的登入,而我们最常见的就是QQ,微信,在没有踏入程序员这条不归路之前,看到一个个的界面都感觉好高大上的样子. 在学习的过程中,自 ...
随机推荐
- JAX-RPC
JAX-RPC(基于可扩展标记语言XML的远程过程调用的Java应用程序接口)是Java Web服务开发包(WSDP)的应用程序接口(API),WSDP能使Java开发者在Web服务或其他的Web应用 ...
- Matlab编程实例(2) 同期平均
%多点同期平均 close all; clear all; pi = 3.14159; Samp2=input('您需要几组信号做同期平均?') Samp1=1000 %设置采样精度 t = lins ...
- 使用std::function 把类成员函数指针转换为普通函数指针
前言 这是改造前一篇 设计模式 的基础,使通知者不必知道观察者的类名和函数名,只需要知道更新函数的原型即可. 开发环境:WIN7 32位 + VS2010 发现在VS2005中使用std::funti ...
- ubuntu下php5扩展mysqli
看网上说的都是自己编译源码,试了一下其实这样就可以了 sudo apt-get instal php5-mysql
- 用Windows Live Writer发来
文字 package com.myeclipseide.example.myblog.secure; import com.opensymphony.xwork2.ActionSupport; ...
- centos 安装git 服务端
// 在服务端安装好git后,开始安装gitosis 3.在服务器安装gitosis sudo yum install python python-setuptools cd /usr/local/s ...
- 转】机器学习开源框架Mahout配置与入门研究
原博文出自于:http://www.ha97.com/5803.html 感谢! PS:机器学习这两年特别火,ATB使劲开百万到几百万年薪招美国牛校的机器学习方向博士,作为一个技术控,也得折腾下 ...
- Java设计模式系列之责任链模式
责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道 ...
- ios游戏开发 Sprite Kit教程:初学者 1
注:本文译自Sprite Kit Tutorial for Beginners 目录 Sprite Kit的优点和缺点 Sprite Kit vs Cocos2D-iPhone vs Cocos2D- ...
- Light oj 1236 - Pairs Forming LCM (约数的状压思想)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1236 题意很好懂,就是让你求lcm(i , j)的i与j的对数. 可以先预处理1e7以 ...