IOS中關於KVC與KVO知識點

來源:互聯網
上載者:User

標籤:style   blog   io   ar   color   os   使用   sp   for   

一、簡介

KVC/KVO是觀察者模式的一種實現,在Cocoa中是以被萬物之源NSObject類實現的NSKeyValueCoding/NSKeyValueObserving非正式協議的形式被定義為基礎架構的一部分。從協議的角度來說,KVC/KVO本質上是定義了一套讓我們去遵守和實現的方法。
當然,KVC/KVO實現的根本是Objective-C的動態性和runtime,這在後文的原理部分會有詳述。
另外,KVC/KVO機制離不開訪問器方法的實現.

1、KVC簡介

全稱是Key-value coding,翻譯成索引值編碼。顧名思義,在某種程度上跟map的關係匪淺。它提供了一種使用字串而不是訪問器方法去訪問一個對象執行個體變數的機制。
2、KVO簡介

全稱是Key-value observing,翻譯成索引值觀察。提供了一種當其它對象屬性被修改的時候能通知當前對象的機制。再MVC大行其道的Cocoa中,KVO機制很適合實現model和controller類之間的通訊。

KVC定義了一種按名稱訪問對象屬性的機制,支援這種訪問的主要方法是:

- (id)valueForKey:(NSString *)key;  - (void)setValue:(id)value forKey:(NSString *)key;  - (id)valueForKeyPath:(NSString *)keyPath;  - (void)setValue:(id)value forKeyPath:(NSString *)keyPath; 

前邊兩個方法用到的Key較容易理解,就是要訪問的屬性名稱對應的字串。
後面兩個方法用到的KeyPath是一個被點操作符隔開的用於訪問對象的指定屬性的字串序列。比如KeyPath address.street將會訪問訊息接收對象所包含的address屬性中包含的一個street屬性。其實KeyPath說白了就是我們平時使用點操作訪問某個對象的屬性時所寫的那個字串。

 

如果要修改對象的屬性值

1.一般情況下是直接利用對象屬性的set方法來修改:

 Student *stu = [[Student alloc] init];   // set方法的兩種書寫格式     [stu setAge:10];    stu.age = 10;

 

2.但是如果不知道物件類型呢?那麼就可以運用KVC索引值編碼(Key Value Coding) 間接的修改對象屬性

KVC實現方式是:使用字串來描述對象需要修改的屬性。

KVC的基本調用包括: valueForKey: 和 setValue:ForKey: 是以字串的方式向對象發送訊息

KVC一般用法:

 

/******************************** 建立Book.h檔案只是為了說明forKeyPath的用法,不用實現 *********************************/#import <Foundation/Foundation.h>@interface Book : NSObject@property (nonatomic,assign) double price; // 書的價格 @end/******************************** Student.h檔案 *********************************/#import <Foundation/Foundation.h>@class Book;@interface Student : NSObject@property(nonatomic,assign) int age;     // 學生年齡@property (nonatomic,copy) NSString *name;  // 學生姓名@property (nonatomic,retain) Book *book;   // 學生擁有書// 測試方法- (void)test;@end/******************************** Student.m檔案 *********************************/#import "Student.h"#import "Book.h"@implementation Student- (void)test{    Student *stu = [[Student alloc] init];        // 1.為基礎資料型別 (Elementary Data Type)單次賦值    [stu setValue:@"John" forKey:@"name"];    NSString *str = [stu valueForKey:@"name"]; // str = John           // 2.為物件類型單次賦值    // setValue 要參數為id類型 因此要先將基礎資料型別 (Elementary Data Type)封裝成物件類型    [stu setValue:@10 forKey:@"age"];    // 根據key值去取出對象後在轉換成為基礎資料型別 (Elementary Data Type)    int age = [[stu valueForKey:@"age"] intValue]; // 10    NSLog(@"%@ %d",str,age); // John 10        // 3.批次的為基礎資料型別 (Elementary Data Type)和物件類型賦值    [stu setValuesForKeysWithDictionary:@{@"age":@20,@"name":@"Jim"}];    // 根據key取出所有的值存入字典    NSDictionary *dic = [stu dictionaryWithValuesForKeys:@[@"name",@"age"]];    NSLog(@"%@",dic); // age = 20;name = Jim        // 4.間接的為Book對象的price屬性賦值    stu.book = [[Book alloc] init]; // 建立stu.book對象// 第一種方式:直接賦值    [stu.book setPrice:20.00]; // price = 20.00    // 第二種方式:通過索引值來賦值    [stu.book setValue:@30.00 forKey:@"price"]; // price = 30.00    // 第三種方式:通過健路徑來賦值    [stu setValue:@40 forKeyPath:@"book.price"]; // price = 40.00        // 索引值和鍵路徑就相當於檔案名稱和檔案路徑名,那麼索引值路徑是包含了索引值的,因此可以使用索引值的時候可以用鍵路徑來代替 那麼的第二種方式也可以寫為    [stu.book setValue:@50 forKeyPath:@"price"]; // price = 50.00    NSLog(@"%.2f",stu.book.price);  // 測試輸出  }@end另外:KVC還提供了運算元組的方法和一些計算的參數

 

 

2.KVO (Key Value Observing) 索引值觀察機制,主要用來監聽對象屬性的變化

實現方式:添加監聽器

舉例:Teacher類要監聽Student類中的name屬性值的變化

 

/***************************** Student.h檔案 *************************************/#import <Foundation/Foundation.h>@interface Student : NSObject@property (nonatomic,copy) NSString *name; // 聲明監聽的屬性// 測試監聽的方法- (void)test;@end


 

/***************************** Student.h檔案 *************************************/#import "Student.h"#import "Teacher.h"@implementation Student- (void)test{    Student *stu = [[Student alloc] init];        // 利用KVC為name屬性賦值    [stu setValue:@"章三" forKey:@"name"];        // 實現Teacher類監聽Student屬性name的變化        // 1.建立監聽對象    Teacher *teacher = [[Teacher alloc] init];        // addOberver是NSObject分類方法 那麼任何對象都可以添加監聽方法        // 2.對student類添加監聽對象teacher options參數:監聽新值還是舊值    // forKeyPath:鍵路徑 context:上下文用於動畫中    [stu addObserver:teacher forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil]; // 這裡只監聽了新值 當然也可以一起監聽 option: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld        // 修改了Student類name屬性的值 就會通知監聽器 Teacher對象 然後調用Teacher類中的    stu.name = @"李斯"; // 監聽對象屬性的值改變後 執行監聽對象的方法    }@end
/***************************** Teacher.h檔案 *************************************/#import <Foundation/Foundation.h>@interface Teacher : NSObject@end
/***************************** Teacher.m檔案 *************************************/#import "Teacher.h"#import "Student.h"@implementation Teacher// 一旦監聽到Student類中name屬性值發生變化就會調用監聽器Teacher類中的這個方法 通過參數來說明// keyPath = @"name"; object就是Student類 change:改變後傳到的值是新值還是舊值 還是新舊值都有對應的是監聽器中的option參數- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{    NSLog(@"keyPath:%@",keyPath);   // keyPath:name    NSLog(@"objcet:%@",object);     // object:Student    NSLog(@"change:%@",change);     // \U674e\U65af  漢字被轉義}@end

 

/***************************** mian.m檔案 *************************************/#import <Foundation/Foundation.h>#import "Student.h"int main(int argc, const char * argv[]){    @autoreleasepool {                // 測試        Student *stu = [[Student alloc] init];        [stu test];    }    return 0;}

IOS中關於KVC與KVO知識點

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.