http://funnyrella.blogspot.com/2013/10/27.html


27. 키-밸류 코딩(KVC : Key-Value Coding)

:  Objective C가 아니라 코코아가 제공하는 인다이렉션
:  클래스의 함수나 변수 심지어 프로퍼티를 "키"값으로 불러서 사용 혹은 설정할 수 있다.
JAVA 리플렉션을 이용하여 클래스의 인스턴스를 얻지 않고 메소드나 변수에 접근할 수 있는데 거의 유사한 듯 한데…?

a. 기본
을 얻을 때   -valueForKey:
값을 셋팅할 때  -setValue:forkey:
   NSLog(@"horsepower is %@", [engine valueForKey:@"horsepower"]);
   [engine setValue:[NSNumber numberWithInt:150forKey:@"horsepower"];

b. 경로
!!! 와우!!!! 심지어 클래스를 따라 따라서도 접근이 가능하다…
을 얻을 때   -valueForKeyPath:
값을 셋팅할 때  -setValue:forkeyPath:  
   [car setValue: [NSNumber numberWithInt155forKeyPath@"engine.horsepower"];
    NSLog(@"horsepower is %@", [car valueForKeyPath@"engine.horsepower"]);

c. Array의 값을 찾아서 다시 Array로 전달
   NSArray *pressures = [car valueForKeyPath@"tires.pressure"];
   NSLog (@"pressures %@", pressures);

d. 연산자 사용 
: 키경로에 객체 값 외에 몇몇 연산자를 사용하여 배열의 값의 평균, 합계, 갯수, 최대/최소값을 구할 수 있다
   NSNumber *count = [garage valueForKeyPath:@"cars.@count"];
   NSLog(@"We have %@ cars", count);

e. 키값을 한방에 수정
한방에 가져오기 : 원하는 키만 모아서 가져오기
   NSArray *keys = [NSArray arrayWithObjects:@"make"@"model"@"modelYear"nil];
   NSDictionary *carValues = [car dictionaryWithValuesForKeys:keys];
   NSLog(@"Car values : %@", carValues);

한방에 수정: 일부 키를 한방에 수정
   NSDictionary *newValues = [NSDictionary dictionaryWithObjectsAndKeys:
                @"Chevy"@"make",
                @"Nova"@"model",
                [NSNumber numberWithInt:1964], @"modelYear",
                [NSNumber numberWithFloat:987.6], @"mileage",
                nil];
  [car setValuesForKeysWithDictionary:newValues];

f. 비정의 값 처리 : 오버라이드 함수 구현해주면 됨
비정의 키에 대해서 설정할 때 처리함수
- (void) setValue:(id)value forUndefinedKey:
비정의 키에 대해서 값을 참고하려 할 때 처리함수
- (id) valueForUndefinedKey:


[참고] iOS 프로그래밍에서…
클래스간의 의존성을 낮출수록 좀 더 좋은 코드라고 한다. 키밸류코딩은 이러한 클래스간 의존성을 낮추는, 즉 느슨한 결합이 된 코드를 사용할 수 있다는 장점이 있다.
이경우 키밸류코딩의 단점은 상대클래스를 직접 호출하는 것이 아니므로 코드 가독성이 떨어질 수 있다. 또, 오타로 인해 버그로 이어질수도 있는 만큼 키-값 코딩을 남용해서는 안된다.
ex) 뷰콘트롤러의 Segue기능에서, 선택하면  Segue할 목적콘트롤러에게 값을 주기위해서 함수를 호출하는 방식에서 키밸류코딩을 사용한 경우
<키밸류코딩사용>
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UIViewController *destination = segue.destinationViewController;
    if ([destination respondsToSelector:@selector(setDelegate:)]) { //@property delegate 대한 세터 혹은 setDelegate함수
        [destination setValue:self forKey:@"delegate"]; //키밸류코딩(KVC) 활용
    }
}
이 코딩을 직접메소드호출한다면… 임포트도 해야하고, 캐스팅도 해야한다. 즉 받는 애가 어떤 클래서인지 정확히 알고 갸의 메소드를 불러줘야 한다.
#import "BIDTaskDetailController.h"
...
//받는클래스가 어떤애인지 정확히 알고 캐스팅해야한다.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    BIDTaskDetailController *destination = (BIDTaskDetailController *)segue.destinationViewController
    if (destination != nil) {
        destination.delegate = self;
    }

}