目錄
前言
1.iOS中的KVC(鍵值編碼)
1. 什么是KVC?
2. 使用KVC
1.設置屬性值
2.獲取屬性值
3. KVC的高級用法
1.訪問私有屬性
2.訪問集合屬性
4. KVC的安全性
5. KVC原理
1. 查找順序
2. 設置值
6.參考文章
前言
? ? ? ? 這篇文章主要是介紹KVC的用法。
1.iOS中的KVC(鍵值編碼)
????????在iOS開發中,KVC(Key-Value Coding,鍵值編碼)是一種強大的機制,使得我們能夠通過字符串鍵來訪問對象的屬性。KVC在許多iOS框架和技術中扮演著關鍵角色,包括Core Data、Cocoa Bindings以及KVO(Key-Value Observing,鍵值觀察)。
1. 什么是KVC?
????????KVC是一種間接訪問對象屬性的方法。通常,我們通過屬性的getter和setter方法來訪問或修改對象的屬性。但使用KVC,我們可以通過字符串鍵來訪問這些屬性,這使得代碼更加靈活和動態。
2. 使用KVC
????????KVC主要通過setValue:forKey和valueForKey:方法來實現。
1.設置屬性值
#import <Foundation/Foundation.h>@interface Person : NSObject@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;@end@implementation Person
@endint main(int argc, const char * argv[]) {@autoreleasepool {Person *person = [[Person alloc] init];// 使用KVC設置屬性值[person setValue:@"John" forKey:@"name"];[person setValue:@30 forKey:@"age"];NSLog(@"Name: %@", person.name);NSLog(@"Age: %ld", (long)person.age);}return 0;
}
2.獲取屬性值
int main(int argc, const char * argv[]) {@autoreleasepool {Person *person = [[Person alloc] init];[person setValue:@"John" forKey:@"name"];[person setValue:@30 forKey:@"age"];// 使用KVC獲取屬性值NSString *name = [person valueForKey:@"name"];NSNumber *age = [person valueForKey:@"age"];NSLog(@"Name: %@", name);NSLog(@"Age: %@", age);}return 0;
}
3. KVC的高級用法
1.訪問私有屬性
????????KVC不僅可以訪問公共屬性,還可以訪問私有屬性。盡管這是KVC的一個強大功能,但在實際開發中要謹慎使用。
@interface Person ()@property (nonatomic, strong) NSString *secret;@end@implementation Person
@endint main(int argc, const char * argv[]) {@autoreleasepool {Person *person = [[Person alloc] init];// 使用KVC訪問私有屬性[person setValue:@"This is a secret" forKey:@"secret"];NSString *secret = [person valueForKey:@"secret"];NSLog(@"Secret: %@", secret);}return 0;
}
2.訪問集合屬性
????????KVC還提供了一些便捷方法來訪問集合類型的屬性,如數組和字典。
@interface Group : NSObject@property (nonatomic, strong) NSArray<Person *> *members;@end@implementation Group
@endint main(int argc, const char * argv[]) {@autoreleasepool {Person *person1 = [[Person alloc] init];[person1 setValue:@"Alice" forKey:@"name"];[person1 setValue:@25 forKey:@"age"];Person *person2 = [[Person alloc] init];[person2 setValue:@"Bob" forKey:@"name"];[person2 setValue:@28 forKey:@"age"];Group *group = [[Group alloc] init];group.members = @[person1, person2];// 使用KVC訪問集合屬性NSArray *names = [group valueForKeyPath:@"members.name"];NSLog(@"Names: %@", names);}return 0;
}
4. KVC的安全性
????????使用KVC時需要注意一些安全性問題,例如:
????????- 如果指定的鍵不存在,KVC會拋出一個異常。
????????- 訪問或修改私有屬性可能違反封裝性原則。
????????因此,使用KVC時要確保鍵的正確性,并且要對可能出現的異常進行適當的處理。
5. KVC原理
????????KVC 的實現主要依賴于以下幾個方面:
1. 查找順序
? ? ?????????當通過 `valueForKey:` 獲取值時,KVC 按以下順序查找屬性:
- Getter 方法:首先查找與鍵對應的 getter 方法。例如,對于鍵 `name`,查找 `getName`、`name` 或 `isName` 方法。
- ?實例變量:如果沒有找到合適的 getter 方法,則查找以鍵命名的實例變量 `_name` 或 `name`
- ? -accessInstanceVariablesDirectly:如果前兩個查找都失敗,KVC 會調用 `accessInstanceVariablesDirectly` 方法,該方法返回 YES 表示可以直接訪問實例變量。
2. 設置值
????????當通過setValue:forKey:設置值時,KVC 按以下順序查找屬性:
- Setter 方法:首先查找與鍵對應的 setter 方法。例如,對于鍵 name,查找 setName:?方法。
- 實例變:如果沒有找到合適的 setter 方法,則查找以鍵命名的實例變量_name或 name
- setValue:forUndefinedKey:如果前兩個查找都失敗,KVC 會調用 `setValue:forUndefinedKey:` 方法,該方法通常會拋出一個異常。
#### KVC 的查找規則示例
@interface Person : NSObject {NSString *_name;
}
@property (nonatomic, strong) NSString *name;
@end@implementation Person
@end
當調用 `[person valueForKey:@"name"]` 時,KVC 的查找順序如下:
1. 查找 `- (NSString *)name` 方法。
2. 查找 `- (NSString *)getName` 方法。
3. 查找 `- (NSString *)isName` 方法。
4. 查找實例變量 `_name` 和 `name`。
5. 調用 `accessInstanceVariablesDirectly` 方法,返回 YES,直接訪問 `_name`。
當調用 [person setValue:@"John" forKey:@"name"]?時,KVC 的查找順序如下:
1. 查找 - (void)setName:(NSString *)name?方法。
2. 查找實例變量 `_name` 和 `name`。
3. 調用 `setValue:forUndefinedKey:` 方法。
6.參考文章
1.Key-Value Coding Programming Guide: About Key-Value Coding