標籤:style blog http io 使用 ar for strong 檔案
簡介:
上篇我們講到了KVC,這篇我們學習KVO,全名為:Key Value Observing,直譯為:基於索引值的觀察者。
那它有什麼用呢?KVO主要用於視圖互動方面,比如介面的某些資料變化了,介面的顯示也跟著需要變化,那就要建立資料和介面的關聯。
ObjC中提供的KVO就是解決這種問題的。以下用顯示頁面觀察學生的課程名稱變化的例子來說明KVO的使用。
學生類命名為:Student,頁面類是:PageView.
來自蘋果官網:圖中的BankObject好比PageView,PersonObject好比Student,
PageView觀察Student的變化。
1、添加Student學生類。
.h
#import <Foundation/Foundation.h>@interface Student : NSObject{ NSString *name; NSString *courseName;}-(void)changeCourseName:(NSString*) newCourseName;@end
類中有name,和課程名稱courseName,添加一個可以改變課程名稱的方法changeCourseName。一會用來做對比,看直接改變課程名稱時會不會有回調。
實現檔案.m
#import "Student.h"@implementation Student-(void)changeCourseName:(NSString*) newCourseName{ courseName = newCourseName;}@end
實作類別把方法實現了。
2、頁面類實現
.h檔案
#import <Foundation/Foundation.h>@class Student;@interface PageView : NSObject{ Student *student;}-(id)init:(Student*)initStudent;@end
.m檔案
#import "PageView.h"#import "Student.h"@implementation PageView-(id)init:(Student*)initStudent{ if (self = [super init]) { student = initStudent; [student addObserver:self forKeyPath:@"courseName" options:NSKeyValueObservingOptionOld |NSKeyValueObservingOptionNew context:nil]; } return self;}- (void) dealloc{ [student removeObserver:self forKeyPath:@"courseName" context:nil]; [super dealloc]; }-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqual:@"courseName"]) { NSLog(@"PageView課程被改變了"); NSLog(@"PageView新課程是:%@ 老課程是:%@", [change objectForKey:@"new"],[change objectForKey:@"old"]); }}@end
init初始化時,向student執行個體添加觀察者,在釋放的時候移除觀察者。
3、實現觀察
在main函數中
#import "Student.h"#import "Course.h"#import "PageView.h"int main(int argc, const char * argv[]){ @autoreleasepool { Student *student = [[[Student alloc]init]autorelease]; [student changeCourseName:@"數學課"]; NSLog(@"初始值:%@", [student valueForKey:@"courseName"]); //建立頁面執行個體 PageView *pageview = [[[PageView alloc]init:student]autorelease]; [student setValue:@"化學課" forKey:@"courseName"]; } return 0;}
建立一個student的執行個體,設定他的課程是數學課,然後建立頁面類的時候,用student初始化。這是頁面類已經觀察著學生的課程了。
再給課程設定新的值為化學課。這時候運行列印結果:
2012-07-24 16:29:21.561 objectiveC[2192:403] 初始值:數學課
2012-07-24 16:29:21.565 objectiveC[2192:403] PageView課程被改變了
2012-07-24 16:29:21.566 objectiveC[2192:403] PageView新課程是:化學課 老課程是:數學課
可以看到Pageview類中的回調被調用,Pageview接收到學生課程資料更新的資訊。
4、直接改變課程資訊對比
#import "Student.h"#import "Course.h"#import "PageView.h"int main(int argc, const char * argv[]){ @autoreleasepool { Student *student = [[[Student alloc]init]autorelease]; [student changeCourseName:@"數學課"]; NSLog(@"初始值:%@", [student valueForKey:@"courseName"]); //建立頁面執行個體 PageView *pageview = [[[PageView alloc]init:student]autorelease]; [student setValue:@"化學課" forKey:@"courseName"]; [student changeCourseName:@"英語課"]; NSLog(@"直接改變的課程為:%@", [student valueForKey:@"courseName"]); } return 0;}
直接調用changeCourseName方法改變課程,列印結果:
2012-07-24 16:32:06.230 objectiveC[2240:403] 初始值:數學課
2012-07-24 16:32:06.237 objectiveC[2240:403] PageView課程被改變了
2012-07-24 16:32:06.238 objectiveC[2240:403] PageView新課程是:化學課 老課程是:數學課
2012-07-24 16:32:06.239 objectiveC[2240:403] 直接改變的課程為:英語課
可以看到,這時Pageview的回調沒被調用到。說明只有通過索引值編碼(KVC)改變的值,才會回調觀察者註冊的方法。
這裡是蘋果官網的關於KVO的文檔,英文好的朋友可以看看:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA
Objective-C文法之KVO的使用