如果要修改對象的屬性值
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.為基本數據類型單次賦值 [stu setValue:@"John" forKey:@"name"]; NSString *str = [stu valueForKey:@"name"]; // str = John // 2.為對象類型單次賦值 // setValue 要參數為id類型 因此要先將基本數據類型包裝成對象類型 [stu setValue:@10 forKey:@"age"]; // 根據key值去取出對象後在轉換成為基本數據類型 int age = [[stu valueForKey:@"age"] intValue]; // 10 NSLog(@"%@ %d",str,age); // John 10 // 3.批次的為基本數據類型和對象類型賦值 [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;