KVC의 원리 실현
KVC란?
공식 문서:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/KeyValueCoding/index.html#//apple_ref/doc/uid/10000107i
KVC(Key-Value Coding)는 Objective-C가 제공하는 문자열을 이용하여 대상 속성에 간접적으로 접근하는 메커니즘으로 액세서리를 통해 대상 속성에 접근하는 또 다른 선택할 수 있는 방안이다.비공식 프로토콜인 NSKeyValueCoding은 인터페이스를 정의했고 NSObject에서 인터페이스의 기본 구현을 제공했다.
2. 흔한 방법
//
- (nullable id)valueForKey:(NSString *)key;
- (nullable id)valueForKeyPath:(NSString *)keyPath;
- (nullable id)valueForUndefinedKey:(NSString *)key;
//
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;
//
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
- (void)setNilValueForKey:(NSString *)key;
3. KVC 원리
헤더 파일 찾기 NSKeyValueCoding.h 주석은 KVC의 실행 과정을 발견할 수 있습니다
-get
, -
, -is
인 방법은 찾으면 직접 호출하고 방법이 되돌아오는 결과 형식이 바늘 형식이면 직접 되돌아온다.메소드 반환 결과 유형이 수량 유형이 NSNumber 변환을 지원하는 경우 NSNumber로 반환하고 그렇지 않으면 NSValue로 변환하여 반환합니다(임의의 유형의 결과가 NSValue로 변환되면 NSPoint, NSRect와 NSSize는 물론).-countOf
, -indexInOfObject:
, -objectInAtIndex:
과 -AtIndexes:
을 찾습니다.count 방법, index 방법과 다른 두 방법 중 최소한 한 방법을 찾으면 NSOrderedSet의 모든 방법에 응답할 수 있는 대리 집합 대상(NSKeyValueOrderedSet)을 되돌려줍니다.모든 NSOrderedSet 메시지가 에이전트 집합 대상에게 발송될 때, 메시지가 원시 수신기에 발송된 valueForKey:
은 -countOf
, -indexInOfObject:
, -objectInAtIndex:
과 -AtIndexes:
의 조합으로 되돌아옵니다.선택할 수 있는 방법인 -get:range:
을 실현하면 방법도 성능 최적화에 사용될 것이다.-countOf
, -objectInAtIndex:
과 -AtIndexes:
을 찾으며,count 방법과 다른 두 방법 중 최소한 한 방법을 찾으면 NSArray의 모든 방법에 응답할 수 있는 프록시 집합 대상을 되돌려줍니다.모든 NSArray 메시지가 대리 집합 대상에게 발송될 때(NSKey Value Array), 메시지가 원시 수신기에 발송된 valueForKey:
은 -countOf
, -objectInAtIndex:
과 -AtIndexes:
의 조합으로 되돌아온다.선택할 수 있는 방법인 -get:range:
을 실현하면 방법도 성능 최적화에 사용될 것이다.-countOf
, -enumeratorOf
, -memberOf:
을 찾고, 세 가지 방법을 모두 찾으면 NSSet의 모든 방법에 응답할 수 있는 에이전트 집합 대상 (NSKeyValueSet) 을 되돌려줍니다.각 NSSet 메시지가 프록시 컬렉션 객체에 전송되면 원래 수신기에 valueForKey:
메시지가 -countOf
, -enumeratorOf
및 -memberOf:
의 조합으로 반환됩니다._< key >
, _is< Key >
, < key >
또는 is< Key >
에 맞는 실례 변수를 순서대로 찾습니다.인스턴스 변수가 발견되면 인스턴스 변수의 값을 반환하고 NSNumber 및 NSValue 동기화를 급격히 변환합니다.-valueForUndefinedKey:
을 호출하여 결과를 되돌려줍니다.-valueForUndefinedKey:
의 기본 구현은 NSUndefinedKeyException 이상을 던지는 것입니다. 그러나 이 방법을 덮어씁니다.참고: 컬렉션(NSArray, NSSet, NSOrderSet)의 경우 일반 객체처럼 프록시 객체로 돌아가려면 다음과 같은 방법이 필요합니다. NSArray
NSSet
NSOrderSet
-countOf
-countOf
-countOf
-enumeratorOf
-indexInOfObject:
One of
-memberOf:
One of
-objectInAtIndex:
-objectInAtIndex:
-AtIndexes:
-AtIndexes:
Optional (performance)
Optional (performance)
-get:range:
-get:range:
-set:
.이 방법을 찾으면 매개변수 유형을 체크합니다.매개 변수 형식이 대상 포인터 형식이 아니지만 값이 nil이면 -setNilValueForKey:
방법을 사용합니다. -setNilValueForKey:
방법의 기본 구현은 NSInvalid Argument Exception 이상을 던지는 것입니다. 그러나 이 방법을 덮어쓸 수 있습니다.그렇지 않으면 방법 매개 변수 형식이 대상 포인터 형식이라면 이 방법을 직접 호출하여value를 매개 변수로 전송합니다.메소드 매개변수 유형이 다른 유형이면 NSNumber/NSValue의 역변환은 메소드 -valueFor
이 호출될 때 수행됩니다._< key >
, _is< Key >
, < key >
또는 is< Key >
의 실례 변수를 순서대로 찾습니다.실례 변수를 찾았고, 그 형식이 대상 바늘 형식이라면, 이전 값에 대해release 작업을 한 다음value에 대해retain 작업을 하고, 실제 변수에 값을 부여합니다.다른 유형의 경우 1단계에서 NSNumber/NSValue를 변환한 다음 값을 지정합니다.setValue:forUndefinedkey:
방법을 사용합니다. setValue:forUndefinedkey:
방법의 기본 구현은 NSUndefinedKeyException 이상을 던지는 것입니다. 그러나 이 방법을 덮어쓸 수 있습니다.-mutableArrayValueForKey:key
-mutableOrderedSetValueForKey:key
-mutableSetValueForKey:key
기본 액세스 방법은 -valueForKey:key
과 같습니다.프록시 대상을 되돌릴 때 실현해야 할 방법은 다르다.NSMutableSet
At least 1 insertion and 1 removal method
* At least 1 addition and 1 removal method
-insertObject:inAtIndex:
-addObject:
-removeObjectFromAtIndex:
-removeObject:
-insert:atIndexes:
-add:
-removeAtIndexes:
-remove:
Optional (performance) one of
* Optional (performance)
-replaceObjectInAtIndex:withObject:
-intersect:
-replaceAtIndexes:with:
-set:
4. 실례
1. YKNoteKVCObject 클래스 만들기
//
// YKNoteKVCObject.h
// YKNote
//
// Created by wanyakun on 2016/11/10.
// Copyright © 2016 com.ucaiyuan. All rights reserved.
//
#import
@interface YKNoteKVCObject : NSObject {
NSInteger _intVar;
NSString *_strVar;
}
@property (nonatomic, assign) NSInteger intProperty;
@property (nonatomic, copy) NSString *strProperty;
@end
//
// YKNoteKVCObject.m
// YKNote
//
// Created by wanyakun on 2016/11/10.
// Copyright © 2016 com.ucaiyuan. All rights reserved.
//
#import "YKNoteKVCObject.h"
@implementation YKNoteKVCObject
@synthesize intProperty = _intProperty;
@synthesize strProperty = _strProperty;
#pragma mark - method for orderSet
- (NSUInteger)countOfOrderSet {
NSLog(@"%s", __PRETTY_FUNCTION__);
return 5;
}
- (NSInteger)indexInOrderSetOfObject:(id)element {
return 2;
}
- (id)objectInOrderSetAtIndex:(NSUInteger)index {
NSLog(@"%s", __PRETTY_FUNCTION__);
return [NSString stringWithFormat:@"orderSet_%ld", index];
}
#pragma mark - method for array
- (NSUInteger)countOfArray {
NSLog(@"%s", __PRETTY_FUNCTION__);
return 10;
}
- (id)objectInArrayAtIndex:(NSUInteger)index {
NSLog(@"%s", __PRETTY_FUNCTION__);
return [NSString stringWithFormat:@"array_%ld", index];
}
#pragma mark - mehtod for set
- (NSUInteger)countOfSet {
NSLog(@"%s", __PRETTY_FUNCTION__);
return 15;
}
- (NSEnumerator *)enumeratorOfSet {
NSLog(@"%s", __PRETTY_FUNCTION__);
NSEnumerator *enumerator = [[NSEnumerator alloc] init];
return enumerator;
}
- (NSString *)memberOfSet:(NSString *)object {
NSLog(@"%s", __PRETTY_FUNCTION__);
return [NSString stringWithFormat:@"member of set: %@", object];
}
#pragma mark - method for MutableOrderedSet
- (void)insertObject:(NSString *)object inMOrderSetAtIndex:(NSUInteger)index {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)removeObjectFromMOrderSetAtIndex:(NSUInteger)index {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
#pragma mark - method for MutableArray
- (void)insertObject:(NSString *)object inMArrayAtIndex:(NSUInteger)index {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)removeObjectFromMArrayAtIndex:(NSUInteger)index {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
#pragma mark - method for mutableSet
- (void)addMSetObject:(NSString *)object {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)removeMSetObject:(NSString *)object {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
#pragma mark - private method
- (id)valueForUndefinedKey:(NSString *)key {
NSLog(@"%s
ValueForUndefinedKey:%@", __PRETTY_FUNCTION__, key);
return @"undefinedKeyValue";
}
- (void)setNilValueForKey:(NSString *)key {
NSLog(@"%s
NilValueKey:%@", __PRETTY_FUNCTION__, key);
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
NSLog(@"%s
undefineKey:%@", __PRETTY_FUNCTION__, key);
}
+ (BOOL)accessInstanceVariablesDirectly {
return YES;
}
#pragma mark getter setter
- (NSInteger)intProperty {
NSLog(@"%s", __PRETTY_FUNCTION__);
return _intProperty;
}
- (void)setIntProperty:(NSInteger)intProperty {
NSLog(@"%s", __PRETTY_FUNCTION__);
_intProperty = intProperty;
}
- (NSString *)strProperty {
NSLog(@"%s", __PRETTY_FUNCTION__);
return _strProperty;
}
- (void)setStrProperty:(NSString *)strProperty {
NSLog(@"%s", __PRETTY_FUNCTION__);
_strProperty = [strProperty copy];
}
@end
2. setValue:ForKey:와valueForKey:등을 호출할 Controller 만들기
//
// YKNoteKVCViewController.m
// YKNote
//
// Created by wanyakun on 2016/11/11.
// Copyright © 2016 com.ucaiyuan. All rights reserved.
//
#import "YKNoteKVCViewController.h"
#import "YKNoteKVCObject.h"
#import
@interface YKNoteKVCViewController ()
@property (nonatomic, strong) YKNoteKVCObject *yKNoteKVCObject;
@end
@implementation YKNoteKVCViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"KVC";
self.view.backgroundColor = [UIColor whiteColor];
//
[self.yKNoteKVCObject setValue:[NSNumber numberWithInteger:10] forKey:@"intProperty"];
NSInteger intProperty = [[self.yKNoteKVCObject valueForKey:@"intProperty"] integerValue];
NSLog(@"intProperty = %ld", intProperty);
[self.yKNoteKVCObject setValue:@"I am strProperty" forKey:@"strProperty"];
NSString *strProperty = [self.yKNoteKVCObject valueForKey:@"strProperty"];
NSLog(@"strProperty = %@", strProperty);
//
[self.yKNoteKVCObject setValue:[NSNumber numberWithInteger:20] forKey:@"intVar"];
NSInteger intVar = [[self.yKNoteKVCObject valueForKey:@"intVar"] integerValue];
NSLog(@"intVar = %ld", intVar);
[self.yKNoteKVCObject setValue:@"I am strVar" forKey:@"strVar"];
NSString *strVar = [self.yKNoteKVCObject valueForKey:@"strVar"];
NSLog(@"strVar = %@", strVar);
//set undefineKey
[self.yKNoteKVCObject setValue:@"undefine value" forKey:@"undefinedKey"];
// Object pointer nil
[self.yKNoteKVCObject setValue:nil forKey:@"intProperty"];
//NSOrderSet, NSArray, NSSet
id orderSet = [self.yKNoteKVCObject valueForKey:@"orderSet"];
id array = [self.yKNoteKVCObject valueForKey:@"array"];
id set = [self.yKNoteKVCObject valueForKey:@"set"];
NSLog(@"
orderSet class:%@
array class:%@
set class:%@", object_getClass(orderSet), object_getClass(array), object_getClass(set));
//NSMutableOrderSet, NSMutableArray, NSMutableSet
id mutableOrderSet = [self.yKNoteKVCObject mutableOrderedSetValueForKey:@"mOrderSet"];
id mutableArray = [self.yKNoteKVCObject mutableArrayValueForKey:@"mArray"];
id mutableSet = [self.yKNoteKVCObject mutableSetValueForKey:@"mSet"];
NSLog(@"
mutableOrderSet class:%@
mutableArray class:%@
mutableSet class:%@", object_getClass(mutableOrderSet), object_getClass(mutableArray), object_getClass(mutableSet));
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#pragma mark - getter
- (YKNoteKVCObject *)yKNoteKVCObject {
if (_yKNoteKVCObject == nil) {
_yKNoteKVCObject = [[YKNoteKVCObject alloc] init];
}
return _yKNoteKVCObject;
}
@end
3. 결과 내보내기
-[YKNoteKVCObject setIntProperty:]
-[YKNoteKVCObject intProperty]
intProperty = 10
-[YKNoteKVCObject setStrProperty:]
-[YKNoteKVCObject strProperty]
strProperty = I am strProperty
intVar = 20
strVar = I am strVar
-[YKNoteKVCObject setValue:forUndefinedKey:]
undefineKey:undefinedKey
-[YKNoteKVCObject setNilValueForKey:]
NilValueKey:intProperty
orderSet class:NSKeyValueOrderedSet
array class:NSKeyValueArray
set class:NSKeyValueSet
mutableOrderSet class:NSKeyValueFastMutableOrderedSet2
mutableArray class:NSKeyValueFastMutableArray2
mutableSet class:NSKeyValueFastMutableSet2
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.