- 浏览: 675974 次
- 性别:
- 来自: 深圳
最新评论
-
fingerplay:
请问一下,第一份,逻辑树,就是代码里可以操纵的,例如更改lay ...
UIView与CALayer -
ok_lyc:
分享到哪里去了
iPhoneUIFont各种字体 -
lliiqiang:
我的个人理解:wait方法是在java虚拟机层面上在获取对象锁 ...
JAVA多线程同步wait、notify、synchronized -
milixw:
谢谢分享,就在找这个
iphone 推送通知 java 实现 -
wsqwsq000:
你的log4j包不行,上网搜一下:log4j-1.2.16.j ...
iphone 推送通知 java 实现
One of the things I like most about Apple’s iOS SDK is the consistent and easy-to-use API they provide. Across all their different frameworks there’s a pattern at work that makes using their classes easy to understand. This is due in part to the simplicity for configuring those objects. In most cases you don’t need to call cryptic methods to setup or teardown classes. If you want to change a label’s font, you just set a property. If you want to add a new set of tabs to a UITabBarController, you simply have to assign an array of view controllers to the “viewControllers” property and away you go. Key-Value-Observing, or more commonly KVO, is a mechanism by which you can observe changes to keys and their values bound to an object. It lets you make arbitrary objects aware of changes made to values in other objects that are important to you. When those values are changed at all, theobserveValueForKeyPath:ofObject:change:context: method is invoked on the listener, or “observer”. In essence, it lets you listen to when people change properties on your object. You might say “Really? That’s all it does? I can get the same by creating a custom setter!” and you might be right, but there’s several reasons why creating custom setters to handle update logic might be undesirable: Using KVO in a class essentially buys you flexibility and easy-to-read code, and with a few general practices can be made easy to read and easy to extend. Many developers getting started with KVO, myself included, typically start by assigning observers for one or two keyPath properties in either their init or viewDidLoad methods. Then, within theirobserveValueForKeyPath:ofObject:change:context: method they will have code to respond to those setting changes. As an example lets assume we’re creating a UIView subclass that has a UIColor property that controls the display of several subviews. When that property changes lets make our view update all our sub-views to the appropriate color. We could do this with a custom setter, like so: For the purposes of this example though, lets utilize KVO for this. In the initWithFrame: method we add ourselves as an observer of the keyPath “color”, passing in the default options. We also define a method that Cocoa Touch uses to notify the observer, in this case “self”, when a keyPath has been changed. This method is invoked for different properties that are changed, so you should always pass the message along to “super” if this method is called for a property you didn’t explicitly add as an observer. While the above code does look longer than the custom setter equivalent, in the long-run this code is much easier to extend over the life of your class, especially as you add more complex behaviors. As my experience with KVO improved, so did my techniques for managing my observers, responding to keyPath value changes, and generally keeping my code clean. One of the things I found was that it is useful to keep a list of the keyPaths you’re observing so that you can conveniently iterate over them programmatically. To illustrate my point, consider an example where you expose multiple subviews as properties, and when some values change you would like to perform some sort of redraw operation. As you can see not only would this be impossible to do with custom setters, but we managed to respond to several different property changes using a single block of code. Additionally, keeping a static NSSet object around with a list of the keys you’re observing is convenient for several reasons: There are other advantages, but this is just the tip of the iceberg. In order to illustrate how to build a more complicated feature using KVO, lets create a UITableViewCell subclass that makes it easy to create a gloss icon in your table cells, just like the iTunes App Store app. If we’re successful we should be able to create a table cell whose icon looks like the screenshot to the right. Instead of requiring us to worry about the details of rendering the gloss icon overlay every time we want to display an app icon, lets create a property on our table cell that encapsulates this behavior. Ideally we should be able to set the app icon’s original image once, and the UITableViewCell imageView.image property should be set to the appropriate content. We could do this with a custom accessor, but I’d like to show you an easy way to do this with KVO. You can see from our interface declaration that we’re adding two properties for the icon image itself, and a boolean indicating whether or not we want the gloss effect. Now lets look at the implementation. This code may seem complicated, but in the end it is very straight-forward. I’m also introducing a few additional concepts here that I’d like to call out specifically. KVO allows you to specify different options for when you’re observing a set of keyPaths. It’s a bit-mask, so you can enable multiple options simultaneously. In this example I’m indicating that I want to be notified of both the old and new values of these properties. When the icon is changed, the change dictionary supplied to our callback tells us both the old and new values of the property. This is a pattern I use which helps for simplicity of code, as well as a defensive coding mechanism. By declaring static NSString variables for each keyPath you’re observing, it ensures you won’t accidentally type the wrong keyPath somewhere in your code. It also gives you a single place for defining, or changing, the keyPath you’re interested in observing. In this example I’m returning early in the block, when the keyPath is not in my set of “ObservableKeys”. This makes the callback code cleaner since you eliminate one extra nested “if” block, and helps to prevent mistakes. I find it useful to extract values from the change dictionary as early as possible, and then cast those values as needed. If you’re not careful your observer callback can get quite large. It’s powerful to be able to have a single point where complex behaviours and patterns can be established between different properties, but you should make sure it doesn’t become overgrown with logic. It’s better to start out by pushing complex logic into private methods, and simply invoke that from within your callback. Apple’s own documentation, as always, is a good source of information but it can tend to be a lot to take in. At this point you should have a basic understanding of how KVO works, and how you can use it in your application. You can also download the sample application created above at Github. Once you get started, finding answers to your questions becomes simpler when you’ve gotten the hang of KVO. Good luck, and happy coding!
This up front simplicity comes at a cost however: somebody had to write code to intercept the setting of those properties and update the view to reflect the changes made. Fortunately for those developers at Apple, Cocoa and Cocoa Touch makes this simple through the use of Key-Value-Observing (KVO). If you know how to use it, you can do the same thing in your applications as well. Read on to see what I do to make implementing KVO in my projects easy and intuitive.
@property
(
nonatomic
,
copy
) UIColor *color;
- (
void
)setColor:(UIColor *)color {
if
(color != color) {
[color release];
color = [color retain];
mTitleLabel.textColor = color;
mDescriptionLabel.textColor = color;
[mButton setTitleColor:color
forState:UIControlStateNormal];
}
}
- (
id
)initWithFrame:(CGRect)frame {
self
= [
super
initWithFrame:frame];
if
(
self
) {
[
self
addObserver:
self
forKeyPath:
@"color"
options:0
context:
nil
];
}
}
- (
void
)observeValueForKeyPath:(
NSString
*)keyPath
ofObject:(
id
)object
change:(
NSDictionary
*)change
context:(
void
*)context
{
if
([keyPath isEqualToString:
@"color"
]) {
mTitleLabel.textColor =
self
.color;
mDescriptionLabel.textColor =
self
.color;
[mButton setTitleColor:
self
.color
forState:UIControlStateNormal];
}
else
{
[
super
observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}
- (
id
)initWithFrame:(CGRect)frame {
if
(ObservableKeys ==
nil
) {
ObservableKeys = [[
NSSet
alloc] initWithObjects:
@"titleLabel.font"
,
@"descriptionLabel.font"
,
// ...
nil
];
}
self
= [
super
initWithFrame:frame];
if
(
self
) {
for
(
NSString
*keyPath in ObservableKeys)
[
self
addObserver:
self
forKeyPath:keyPath
options:0
context:
nil
];
}
}
- (
void
)dealloc {
for
(
NSString
*keyPath in ObservableKeys)
[
self
removeObserver:
self
forKeyPath:keyPath];
[
super
dealloc];
}
- (
void
)observeValueForKeyPath:(
NSString
*)keyPath
ofObject:(
id
)object
change:(
NSDictionary
*)change
context:(
void
*)context
{
if
([ObservableKeys containsObject:keyPath]) {
[
self
redrawView];
}
else
{
[
super
observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}
#import <UIKit/UIKit.h>
@interface
AppStoreItemView : UITableViewCell
@property
(
nonatomic
, retain) UIImage *icon;
@property
(
nonatomic
)
BOOL
iconNeedsGlossEffect;
@end
#import "AppStoreItemView.h"
#import <QuartzCore/QuartzCore.h>
static
NSSet
* ObservableKeys =
nil
;
static
NSString
*
const
IconKeyPath =
@"icon"
;
static
NSString
*
const
IconNeedsGlossEffectKeyPath
=
@"iconNeedsGlossEffect"
;
@interface
AppStoreItemView ()
- (UIImage*)glossImageForImage:(UIImage*)image;
@end
@implementation
AppStoreItemView
@synthesize
icon;
@synthesize
iconNeedsGlossEffect;
- (
id
)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(
NSString
*)reuseIdentifier
{
// Setup our set of observable keys only once
if
(
nil
== ObservableKeys) {
ObservableKeys = [[
NSSet
alloc] initWithObjects:
IconKeyPath,
IconNeedsGlossEffectKeyPath,
nil
];
}
self
= [
super
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:reuseIdentifier];
if
(
nil
!=
self
) {
// Add observers for each of the keyPaths we care about
for
(
NSString
*keyPath in ObservableKeys)
[
self
addObserver:
self
forKeyPath:keyPath
options:(
NSKeyValueObservingOptionOld
|
NSKeyValueObservingOptionNew
)
context:
nil
];
self
.imageView.layer.cornerRadius = 10.0;
self
.imageView.layer.masksToBounds =
YES
;
}
return
self
;
}
- (
void
)dealloc {
// Tidy up and remove all the observers when the view is destroyed
for
(
NSString
*keyPath in ObservableKeys)
[
self
removeObserver:
self
forKeyPath:keyPath
context:
nil
];
[
super
dealloc];
}
- (
void
)observeValueForKeyPath:(
NSString
*)keyPath
ofObject:(
id
)object
change:(
NSDictionary
*)change
context:(
void
*)context
{
// If the keyPath being changed isn't one we care about,
// pass this up to super and return immediately.
if
(![ObservableKeys containsObject:keyPath]) {
[
super
observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
return
;
}
// Fetch the old and new objects from the change dictionary
id
oldObject = [change objectForKey:
NSKeyValueChangeOldKey
];
id
newObject = [change objectForKey:
NSKeyValueChangeNewKey
];
// Detect null values, since the changed object references
// are object references.
if
([
NSNull
null] == (
NSNull
*)oldObject)
oldObject =
nil
;
if
([
NSNull
null] == (
NSNull
*)newObject)
newObject =
nil
;
// Update imageView when the icon is changed
if
([IconKeyPath isEqualToString:keyPath]) {
self
.imageView.image = [
self
glossImageForImage:newObject];
}
// If the gloss effect is changed, refresh the gloss image
else
if
([IconNeedsGlossEffectKeyPath isEqualToString:keyPath]) {
self
.imageView.image = [
self
glossImageForImage:
self
.icon];
}
}
- (UIImage*)glossImageForImage:(UIImage*)image {
// Code goes here to create the gloss image
// and return the resulting image. See the
// sample code for the full example.
return
mergedImage;
}
@end
发表评论
-
iphone开发如何后台播放音频
2012-12-25 14:38 1558<!--?xml version="1.0&q ... -
iPhone开发中使用AVAudioPlayer出现内存泄漏的解决办法
2012-12-25 11:53 3345最近在使用AVAudioPlayer播放音频时,发现 ... -
dispatch多线程
2012-10-31 20:45 1454#define kBgQueue dispat ... -
iPhone开发使用数组排序
2012-10-30 19:18 1787我们以数组的排序为例(也许NSSortDes ... -
用containsObject判断是否存在的问题
2012-10-16 15:37 4561在NSArray或NSMutableArray中想使用c ... -
用NSZombieEnabled解决恼人的EXC_BAD_ACCESS错误
2012-09-17 10:30 1377转载自:http://longtimenoc.com/a ... -
使用xib加载视图后,在dealloc中crash
2012-09-08 11:20 1766最近遇到个问题,就是使用xib加载视图后,经常会 ... -
iPhone中如何获取当前输入法
2012-09-06 16:28 1696如题,在iPhone开发中,我们如何获取当前的输入 ... -
objectForKey和valueForKey的区别
2012-08-24 17:23 2162valueforkey和objectforkey区别 ... -
粒子发射系统中的CAEmitterLayer
2012-08-22 16:00 2518简介:CAEmitterLayer提供了一个基于 ... -
iPhone开发使用UILineBreakMode不精确
2012-07-26 12:02 1551一开始用UILineBre ... -
Xcode方法提示不显示的解决办法
2012-07-24 09:45 1611Xcode方法提示显示的不正确,只显示方法 ... -
NSArray的排序功能sortedArrayUsingSelector
2012-07-18 17:54 2228- (NSArray *)sortedArrayUs ... -
iPhoneUIFont各种字体
2012-07-24 09:45 1559苹果开发者们想在应用中使用不同字体的话,往往会发现 ... -
iPhone使用ASIHTTPRequest请求时,发送了2次请求
2012-07-24 09:45 2554前段时间用到ASIHTTPRequest做请求时, ... -
iPhone开发调用新浪微博OAuth2.0
2012-06-05 02:30 3102就像题目说的,这次的小项目是做一个新浪微博的客 ... -
Iphone cover flow 开源实现
2012-06-04 00:04 886tapkulibrary-CloverFlow ... -
ASIHTTPRequest下载示例(支持断点续传)
2012-07-24 09:45 1593在工程中,我们会常常遇到需要下载的程序,比 ... -
ASIHTTPRequest类库简介和使用说明
2012-07-24 09:45 1693文章转载自:http: ... -
NSUserDefaults 用户偏好设定保存自定义类(序列化)
2012-04-17 23:30 0NSUserDefaults 用户偏好设定保存 ...
相关推荐
简单说明KVO的运行机制,说明KVO的工作原理,一目了然的代码!适合每个人!
KVC 是基于OCRuntime机制,Runtime机制里面可以通过得到实例变量并且访问其私有的成员变量区;实现keyPath中的访问能力;KVO一种通知发送机制,实现一对多,多对一的映射关系
iOS开发·KVO用法,原理与底层实现: runtime模拟实现KVO监听机制(Blcok及Delgate方式).zip,iOS开发·KVO用法,原理与底层实现: runtime模拟实现KVO监听机制(Blcok及Delgate方式)
对于推崇MVC的cocoa而言,kvo应用的地方非常广泛。(这样的机制听起来类 似Notification,但是notification是需要一个发送notification的对象,一般是 notificationCenter,来通知观察者。而kvo是直接通知到观察对象...
使用kvo的关键是一个对象的任何一个属性值改变,都会回调observeValueForKeyPath函数;...NSNotificationCenter 较之于 kvo 可以实现更大的跨度的通信机制,可以为两个无引用关系的两个对象进行通信。
KVC 与 KVO 使用姿势和原理解析
这是一个小的KVO的demo实现的kvo的效果,对于初学kvo的朋友有一些帮助
已经拥有一年经验的你真的了解KVC,KVO吗?也许不!以前我以为自己都有上架项目,这都是太基础的东西,但今天我重新回头看了以前做的笔记,真的是书读百遍,其义自见。
用KVO实现动态改变tableCell里的显示(例子源于《iOS7编程实战》第22章。仅供自己以后学习参考使用
KVO监听UI控件的frame变化,kVO的简单使用
ios kvo原理的实现demo
kvo的ios代码,kvo即创建一个观察者,当观察的对象的属性发生变化时,观察者就会去执行某些相应的事件
里面功能不用kvo和枚举一样是可以实现的,甚至使用了kvo和枚举反而感觉多此一举, 这仅仅只是作为了解和学习参考,因为想不到啥简单的例子,所以搞一个脱裤子放屁的例子
关于ios学习中的通知和kvc,kvo案例的整理,基础的oc学习
这是在项目中是用KVO来进行强化对KVO的深入理解
KVO-----当对象某个属性(例如 demo 中的字符串 name)发生更改时,对象会获得通知,并作出相应处理,本demo用Runtime实现KVO原理。
一句话使用KVO,使用完无需自己移除KVO
使用KVC对属性赋值 使用KVC对属性取值 KVC对数组取值 KVO是key value observing, 它是一种非常重要的机制,允许监听属性值的变化
KVO的简单使用 该工程 简单明了 明确KVO如何使用
KVO,KVC在MAC下的小DEMO,喜欢的换就拿去吧