如果要修改對象的屬性值
1.一般情況下是直接利用對象屬性的set方法來修改:
Student *stu = [[Student alloc] init];
// set方法的兩種書寫格式 [stu setAge:10]; stu.age = 10;
2.但是如果不知道對象類型呢?那么就可以運用KVC鍵值編碼(Key Value Coding) 間接的修改對象屬性
KVC實現(xiàn)方式是:使用字符串來描述對象需要修改的屬性。
KVC的基本調(diào)用包括: valueForKey: 和 setValue:ForKey: 是以字符串的方式向?qū)ο蟀l(fā)送消息
KVC一般用法:
/******************************** 創(chuàng)建Book.h文件只是為了說明forKeyPath的用法,不用實現(xiàn) *********************************/#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.為基本數(shù)據(jù)類型單次賦值 [stu setValue:@"John" forKey:@"name"]; NSString *str = [stu valueForKey:@"name"]; // str = John // 2.為對象類型單次賦值 // setValue 要參數(shù)為id類型 因此要先將基本數(shù)據(jù)類型包裝成對象類型 [stu setValue:@10 forKey:@"age"]; // 根據(jù)key值去取出對象后在轉(zhuǎn)換成為基本數(shù)據(jù)類型 int age = [[stu valueForKey:@"age"] intValue]; // 10 NSLog(@"%@ %d",str,age); // John 10 // 3.批次的為基本數(shù)據(jù)類型和對象類型賦值 [stu setValuesForKeysWithDictionary:@{@"age":@20,@"name":@"Jim"}]; // 根據(jù)key取出所有的值存入字典 NSDictionary *dic = [stu dictionaryWithValuesForKeys:@[@"name",@"age"]]; NSLog(@"%@",dic); // age = 20;name = Jim // 4.間接的為Book對象的price屬性賦值 stu.book = [[Book alloc] init]; // 創(chuàng)建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還提供了操作數(shù)組的方法和一些計算的參數(shù)
2.KVO (Key Value Observing) 鍵值觀察機制,主要用來監(jiān)聽對象屬性的變化
實現(xiàn)方式:添加監(jiān)聽器
舉例:Teacher類要監(jiān)聽Student類中的name屬性值的變化
/***************************** Student.h文件 *************************************/#import <Foundation/Foundation.h>@interface Student : NSObject@property (nonatomic,copy) NSString *name; // 聲明監(jiān)聽的屬性// 測試監(jiān)聽的方法- (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"]; // 實現(xiàn)Teacher類監(jiān)聽Student屬性name的變化 // 1.創(chuàng)建監(jiān)聽對象 Teacher *teacher = [[Teacher alloc] init]; // addOberver是NSObject分類方法 那么任何對象都可以添加監(jiān)聽方法 // 2.對student類添加監(jiān)聽對象teacher options參數(shù):監(jiān)聽新值還是舊值 // forKeyPath:鍵路徑 context:上下文用于動畫中 [stu addObserver:teacher forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil]; // 這里只監(jiān)聽了新值 當然也可以一起監(jiān)聽 option: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld // 修改了Student類name屬性的值 就會通知監(jiān)聽器 Teacher對象 然后調(diào)用Teacher類中的 stu.name = @"李斯"; // 監(jiān)聽對象屬性的值改變后 執(zhí)行監(jiān)聽對象的方法 }@end
/***************************** Teacher.h文件 *************************************/#import <Foundation/Foundation.h>@interface Teacher : NSObject@end
/***************************** Teacher.m文件 *************************************/#import "Teacher.h"#import "Student.h"@implementation Teacher// 一旦監(jiān)聽到Student類中name屬性值發(fā)生變化就會調(diào)用監(jiān)聽器Teacher類中的這個方法 通過參數(shù)來說明// keyPath = @"name"; object就是Student類 change:改變后傳到的值是新值還是舊值 還是新舊值都有對應的是監(jiān)聽器中的option參數(shù)- (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 漢字被轉(zhuǎn)義}@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;}
新聞熱點
疑難解答