- 浏览: 175418 次
- 性别:
- 来自: 济南
最新评论
-
enefry:
如果 请求头是 range bytes=100-100 怎么 ...
[JSP]断点续传多线程链接下载! JSP/Servlet 实现 -
zhw332548183:
请问楼主,为什么 图片截取完毕后,会一直显示 正在保存 ...
从android系统图库中取图片的代码 -
zhw332548183:
请问楼主,为什么 图片截取完毕后,会一直显示 正在保存 ...
从android系统图库中取图片的代码 -
lovebirdegg:
82934162 写道lovebirdegg 写道829341 ...
怎样将xmppframework应用于iphone应用程序开发 -
82934162:
lovebirdegg 写道82934162 写道请问,你现在 ...
怎样将xmppframework应用于iphone应用程序开发
Key-value coding (KVC) 是一种机制. 容许我们通过变量的名字来获取和设置变量的值. 变量的名字是简单的字符串, 不过我们称它为"key" . 比如. 我们有个类叫 Student. 它有个类型为NSString的成员变量 firstName.
@interface Student : NSObject
{
NSString *firstName;
}
...
@ends
如果我们有个Student对象,我们可以这样设置它的firstName
Student *s = [[Student alloc] init];
[s setValue:@"Larry" forKey:@"firstName"];
同时也可以这样获取firstName:
NSString *x = [s valueForKey:@"firstName"];
方 法setValue:forKey: 和 valueForKey定义在NSObject中[又是定义在NSObject中.这表示所有的对象都有这连个方法咯.] 虽然这不象飞机火箭那么复杂.不过这个机制是非常强大有用的. 这一章我们会用一个简单的例子来展示它的威力.
Key-Value Coding
使用XCdoe,新建一个Cocoa Application工程. 命名为KVCFun, 新建一个Objectvie-class文件. 命名为AppController
在Interface Builder, 拖拽一个自定义对象,设置它的类为Appcontroller 如图7.1
第7章: <wbr>Key-Value <wbr>Coding. <wbr>Key-Vaule <wbr>Observing
保存nib文件
回到XCode.打开AppController.h, 添加一个int类型的成员变量fido.
@interface AppController : NSObject
{
int fido;
}
@end
编辑AppController.m, 我们打算创建init方法,通过key-value coding去读取设置变量fido. 当然这看上去有点傻:用复杂的方法去实现一个简单的功能.不过,我们这样做是为了说明问题,而不是实际编程.
这就是那个使用key-value coding的复杂方法. 我们用NSNumber对象来代替int类型.
- (id)init
{
[super init];
[self setValue:[NSNumber numberWithInt:5]
forKey:@"fido"];
NSNumber *n = [self valueForKey:@"fido"];
NSLog(@"fido = %@", n);
return self;
}
key-value 机制会自动把NSNumber转换成int类型去设置fido的值. 编译运行程序,没有什么特别的.我们看到一个空白窗口, 看到"fido=5"打印在cosole里面
假 如我们定义了accessor方法去读取,设置fido.那么它们将被调用. 当然你必须正确的知道accessor方法的名字. getter必须是fido. 而setter必须是setFido: . 注意,这样做不仅仅是因为编码规范. 如果我们的accessor方法名不标准,当使用key-value coding方法时.它们就得不到调用.[很显然这是apple的规定阿.在key-value方法中就是以这样fido 和 setFido的方法名来调用的.如果我们名字取的和它们不一样.当然没有办法调用到了] . 添加fido和setFido:方法
- (int)fido
{
NSLog(@"-fido is returning %d", fido);
return fido;
}
- (void)setFido:(int)x
{
NSLog(@"-setFido: is called with %d", x);
fido = x;
}
同时在AppController.h中声明它们.
- (int)fido;
- (void)setFido:(int)x;
编译运行程序.我们可以看到accessor方法别调用了
绑定 (Binding)
Cocoa中很多图形对象都支持绑定. 如果我们把一个图形对象的属性(比如颜色, 或是值)和一个key,比如fido,绑定起来.那么,图形对象就可以自动和那个key的值同步. 我们添加一个slider,把它到值和fido绑定起来. 看看它们是怎么同步的.
打开MainMenu.nib. 拖拽一个slider到窗口上. 在Attributes Inspector设置slider为Continuous 如图7.2
第7章: <wbr>Key-Value <wbr>Coding. <wbr>Key-Vaule <wbr>Observing
在Bindings Inspector中, 把slider的value和AppController对象的fido key绑定一起.图7.3
第7章: <wbr>Key-Value <wbr>Coding. <wbr>Key-Vaule <wbr>Observing
编译运行程序. 注意到,slider调用valueForKey:方法来获取它的初始值, 这个方法将调用我们的fido方法. 当我们拖动slider, 会调用setValue:forKey: 去更新fido的值,这会调用setFido:方法
[当 slider做init时, 它发现自己和AppController的对象绑定了,那么它肯定就保留了AppController对象的指针. 然后调用了appController的 valueForKey:方法.并且参数为key-fido. 从而fido方法得到调用. 而在更新的时候,同样因为绑定.会调用 appController对象的 setValue:forKey:, 参数为key-fido. 这样setFido也被调用了]
Key-Value Observing
如果我们通过其他途径来改变fido值,又会发送什么呢?slider会跟着改变么?它是怎么知道fido的值改变了呢?
当 slider创建的时候, 它告诉了AppController: 我会一直关注这key-fido[用程序语言来讲,应该是slider注册了一个通知,当fido改变时,会通知sldier. 通知会在后面的章节讲到.它和观察者模式一样]. 任何时候通过accesor方法或是key-value coding方法改变了fido的值,AppController都会发送一个消息通知slider:fido改变了
再次打开MainMenu.nib, 添加一个文本框.把它的值和AppController 的key fido绑定.如图 7.4
第7章: <wbr>Key-Value <wbr>Coding. <wbr>Key-Vaule <wbr>Observing
编 译运行程序, 我们拖动slider, setFido:方法被调用. 同时会给绑定fido的文本框也发送一个通知告知fido被改变了. 文本框会使用valueForKey:来得到fido的新值. 因此,fido的方法被调用 [建议大家可以把断点设置在accessor方法里面,然后看看调用时的运行堆栈,能看到什么呢?]
观察key
前一节,当使用accessor方法或key-value coding方法去改变key的值,观察者可以自动得到改变的通知. 那假如我们直接修改变量的值又会如何?
打开AppController.h, 声明一个新的action方法
- (IBAction)incrementFido:(id)sender;
打开AppController.m,实现该方法
- (IBAction)incrementFido:(id)sender
{
fido++;
NSLog(@"fido is now %d", fido);
}
打开MainMenu.nib, 给窗口添加一个按钮.命名为Increment Fido. Control-drag按钮到AppController对象建立连接. 这个按钮将会触发incrementFido action如图7.5
第7章: <wbr>Key-Value <wbr>Coding. <wbr>Key-Vaule <wbr>Observing
我们希望当点击这个按钮是,slider会跟着移动,而文本框也会刷新. 不幸的是.现在还不行. 试试编译运行看看吧
如果我们要支持给变量赋值,我们必须给这个key的观察者发送通知. 修改incrementFido:方法
- (IBAction)incrementFido:(id)sender
{
[self willChangeValueForKey:@"fido"];
fido++;
NSLog(@"fido is now %d", fido);
[self didChangeValueForKey:@"fido"];
}
编译运行.OK, Increment 按钮可以正常工作了.
还有两个实现方法.第一个,使用key-value coding
- (IBAction)incrementFido:(id)sender
{
NSNumber *n = [self valueForKey:@"fido"];
NSNumber *npp = [NSNumber numberWithInt:[n intValue] + 1];
[self setValue:npp forKey:@"fido"];
}
或者使用accessor方法改变fido
- (IBAction)incrementFido:(id)sender
{
[self setFido:[self fido] + 1];
}
试试修改,然后编译运行看看
图7.6是我们实现的对象关系图. 注意绑定是使用半个箭头来表示
第7章: <wbr>Key-Value <wbr>Coding. <wbr>Key-Vaule <wbr>Observing
Properties 和它们的属性
你可能猜到,我们大量的使用着accessor方法. 从Objective-2.0,apple增加一个新的方法,我们可以通过点号来调用accessor方法. 比如我们有一个对象指针rover,该对象有个getter方法 rex. 那么我们可以这样使用
NSLog(@"Rover's rex is %@", rover.rex);
而要调用setter方法,可以这样
rover.rex = [NSDate date];
在我看来,在已经有发送消息的语法情况下,这是一个愚笨的新特性.所以我不会在这本书中使用这种方法.
编写accessor方法又怎么样?如我对象有12个成员变量,我们需要12个getter和12setter方法么?
-- @property 和 @synthesize
同样在Objective-C2.0中,apple提供了一条非常优雅的方法来节省代码量. 在AppController.h文件. 使用声明一个property来替换fido和setFido:
@interface AppController : NSObject {
int fido;
}
@property(readwrite, assign) int fido;
@end
这行代码和声明setFido:和fido相同
在AppController.m中, 我们使用@synthesize来实现accessor方法. 删除方法fido和setFido: 用下面的代码代替
@synthesize fido;
恩.所有的都能正常工作(当然,我们看不到那些log了)
-- Property的属性
一般,我们这样来声明一个property
@property (attributes) type name;
attributes可以是 readwrite (默认的) 或是 readonly. 如果使用readonly,那么就只有getter方法.
我们也可以通过:assign, retain,copy属性来指定setter方法的工作方式
.assign(默认) 简单的赋值, assign不会对新的值做retain. 如果使用对象类型的参数,同时没有启用garbage collector.我们不要使用assign
. retain: release旧的值,同时retain新值. 这个属性用在参数为Objective-C对象类型时. 如果启用了garbage collector, 它和assign作用一样. [启用了garbage collector. release和retain什么也不做.]
. copy: 对新值做拷贝,把拷贝赋值给变量. 变量为string时,常用该属性.
最 后,我们还可以使用nonatomic属性. 如果我们的程序是多线程的. 那么让setter方法成为atomic是非常重要的. 也就是说, 不同的线程访问同一个setter方法时,不对产生冲突[线程重入]. 如果没有启用garbage collector. 默认的会使用锁机制来保证在同一个时间点,只能由一个线程来调用一个setter方法. 因为创建和使用锁会产生一些资源消耗.所以如果我们能够保证accessor方法不需要atomic. 我们可以使用nonatomic属性来减少这种消耗.
思考: Key Path
通常很多对象会组成对象网络. 比如, 一个人有一个配偶, 而配偶可能有一辆脚踏车, 脚踏车有型号. 如图 7.7
第7章: <wbr>Key-Value <wbr>Coding. <wbr>Key-Vaule <wbr>Observing
我们可以通过key path来得到这个人配偶的脚踏车的型号:
NSString *mn;
mn = [selectedPerson valueForKeyPath:@"spouse.scooter.modelName"];
我们可以说: spouse和scooter是 Person的关联对象.而modelName是Scooter类的属性.
key path支持很多的操作.例如,有一个person序列,我们可以通过key path来求得他们的平均 expectedRaise:
NSNumber *theAverage;
theAverage = [employees valueForKeyPath:@"@avg.expectedRaise"];
以下是一些常用的操作
@avg
@count
@max
@min
@sum
现在,我们大概了解了key path. 我们可以通过程序来进行绑定. 例如, 我们想把一个对象-employeeController中所有的人-arrangedOnjects的期望加薪的平均值显示到一个文本框中. 我们可以使用绑定:
[textField bind:@"value"
toObject:employeeController
withKeyPath:@"arrangedObjects.@avg.expectedRaise"
options:nil];
当然,使用Interface Builder来创建绑定会更简单
使用unbind:来解除绑定:
[textField unbind:@"value"];
思考: Key-Value Observing
文 本框是怎样成为 AppConroller对象 fido key的观察者呢? 当它从nib文件加载时, 文本框把它自己添加成为一个观察者. 如果你想成为一个观察者.代码大概就像这样:[想象一下.可能在NSTextField的 awakFromNib中的代码就是这样写的]
[theAppController addObserver:self
forKeyPath:@"fido"
options:NSKeyValueObservingOld
context:somePointer];
这个方法定义在NSObject中. 意思为:"喂,当fido改变了,通知我一声阿." option和context是随着这个通知fido改变消息一起传送的额外数据. 触发的消息如下[当得到通知,会调用]
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
...
}
在这里.keyPaht为@"fido". object则为AppController. context则为addObserver时给定的somePointer. change为一个NSDictionary对象,保存了原来和新改变的值
发表评论
-
FMDB:我的SQLite救星
2011-08-23 17:08 1345FMDB:我的SQLite救 ... -
统计代码行数
2011-01-04 16:39 2525http://lovebirdegg.appspot. ... -
Universal Static Libraries
2010-04-16 17:02 1166For some reason Apple reserves ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(3)
2010-04-16 15:25 1330原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(2)
2010-04-16 15:22 1825原文地址:http://www.aisidechina.com ... -
how to reverse a nsstring
2010-04-16 10:04 1209原文:http://lovebirdegg.co.tv/201 ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.1
2010-04-14 10:27 1791原文地址:http://www.aisid ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(1)
2010-04-14 10:25 1026原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.4
2010-04-12 17:16 1208原文地址:http://www.aisid ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.3
2010-04-08 08:10 1448《iPhone应用程序开发 ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.2
2010-04-08 08:09 1462原文地址: http://www.aisidechina. ... -
7 tips for using UIWebView
2010-03-26 14:34 2221For an IPhone app I have been b ... -
how to use TouchXML
2010-03-25 21:50 1691iphoen do not have NSXML* libra ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.1
2010-03-25 12:57 1129原文地址:http://www.aisidechina.com ... -
10 个在app store中需要避免的错误(一)
2010-03-19 18:13 1596原文 #1 Creating an Overly Compl ... -
Filtering Fun with Predicate
2010-03-16 09:34 1563原文:http://lovebirdegg.co.tv/201 ... -
《iPhone应用程序开发指南》第一章 1.1(2)
2010-03-12 17:12 2984原文地址: http://www.aisidechina. ... -
《iPhone应用程序开发指南》第一章 1.1(1)
2010-03-12 17:11 2260原文地址: http://www.aisidechina. ... -
《iPhone应用程序开发指南》目录
2010-03-12 17:09 2217原文地址 http://www.ais ... -
《iPhone应用程序开发指南》介绍
2010-03-12 17:07 2854原文地址 http://www.ais ...
相关推荐
burpsuite分块传输插件,一键生成分块传输请求,用于bypass waf等
网络-coding-v3.0.zip网络-coding-v3.0.zip网络-coding-v3.0.zip网络-coding-v3.0.zip网络-coding-v3.0.zip网络-coding-v3.0.zip网络-coding-v3.0.zip网络-coding-v3.0.zip
主要来源是https://github.com/c0ny1/chunked-coding-converter 这里感谢下c0ny1师傅的分享 但基于此基础,这里是我个人已经编译完成好的,省去编译步骤,小白皆可使用,可以直接使用burp导入插件
亮白风格-图解网络-小林coding-v3.0.pdf
图解网络--小林coding 暗黑版+亮白版
H.265音视频标准。 HEVC。 高效率的视频编码。 Infrastructure of audiovisual services - coding of moving video.
mysql-8.0.11-winx64.zip包含my.ini文件, 请修改为自己的安装目录 # 设置mysql的安装目录 basedir=C:\Program Files (x86)\MySQL8018 # 设置mysql数据库的数据的存放目录 datadir=D:\Coding\Data\MysqlData
图解系统-亮白风格-小林coding-v1.0.pdf
暗黑风格-图解网络-小林coding-v3.0.pdf
3. 兼容性增强:Spark 3.0.0兼容Hadoop 3.2,这意味着它可以充分利用Hadoop的新功能,如HDFS erasure coding和YARN的改进,提升了数据安全性和集群管理效率。 4. 机器学习库MLlib更新:Spark的机器学习库MLlib在新...
图解网络-小林coding-暗黑风格-v4.0.pdf
High efficiency video coding Recommendation ITU-T H.265 | International Standard ISO/IEC 23008-2 represents an evolution of the existing video coding Recommendations (ITU-T H.261, ITU-T H.262, ITU-T...
在"Life-coding-master"这个子文件夹中,我们可以期待找到一个结构化的学习路径,可能包括逐步进阶的编程挑战,覆盖了基础的数据结构(如数组、链表、树)到高级的算法(如排序、搜索、图论)。每个主题都可能有对应...
主要介绍了用 CreateFile()函数和WriteFile()函数读写串口的实例,以及设置串口属性的实例.
### 解锁Objective-C的KVC:深入Key-Value Coding的奥妙 Objective-C是一种功能强大且灵活的面向对象编程语言,它在C语言基础上增加了面向对象的特性。自1980年代由Brad Cox和Tom Love设计以来,Objective-C经过...
jdk-8u351安装环境