developer tip

Objective C에서 키-값 코딩 및 키-값 관찰이란 무엇입니까?

copycodes 2020. 11. 26. 18:44
반응형

Objective C에서 키-값 코딩 및 키-값 관찰이란 무엇입니까?


누군가가 간단한 용어 무엇으로 설명 할 수 Key-Value-CodingKey-Value-Observing? Apple 개발자 참조 문서에 대한 링크를 제공하지 마십시오. 나는 그들을 겪었다. 나는 매우 간단한 용어로 설명을 기대합니다.


KVC (Key-Value-Coding)는 문자열을 사용하여 속성 또는 값에 액세스하는 것을 의미합니다.

id someValue = [myObject valueForKeyPath:@"foo.bar.baz"];

다음과 같을 수 있습니다.

id someValue = [[[myObject foo] bar] baz];

KVO (Key-Value-Observing)를 사용하면 속성 또는 값의 변경 사항을 관찰 할 수 있습니다.

KVO를 사용하여 속성을 관찰하려면 문자열로 속성을 식별합니다. 즉, KVC 사용. 따라서 관찰 가능한 객체는 KVC를 준수해야합니다.

[myObject addObserver:self forKeyPath:@"foo.bar.baz" options:0 context:NULL];

키 값 코딩은 단순히 리터럴 구문 대신 문자열을 통해 객체의 속성에 액세스하는 것입니다.

// Here is a new instance of an object
Foo *foo = [[Foo alloc] init];
// Accessing a property called someValue with literal syntax:
[foo someValue];
// Accessing the same property with dot notation
foo.someValue;
// Accessing the same property with Key-Value coding:
[foo valueForKey:@"someValue"];

KVC의 장점은 런타임에 임의의 문자열을 지정할 수 있다는 것입니다 (분명히 이것은 매우 위험 할 수 있음).


키-값 코딩을 사용하면 처음부터 고정 된 속성으로 컴파일되는 코드를 작성할 필요없이 런타임에 문자열을 사용하여 객체의 속성을 가져 오거나 변경할 수 있습니다.

NSNumber* foo = [myPopup valueForKey: @"selectedItemIndex"];
[myPopup setValue: @15 forKey: @"selectedItemIndex"];

이에 대한 좋은 예는 Mac의 NSTableView입니다. 여기서 표시해야하는 모델 개체의 속성에 해당하는 모든 테이블 열에 식별자를 설정 한 다음 데이터 소스는 -valueForKey : /-setValue : forKey :를 호출합니다. 열의 식별자를 키로 사용하고 값은 자체적으로 표시 / 설정합니다. XIB의 테이블보기에 올바른 열을 추가하기 만하면됩니다.

나중에 키-값 관찰이 추가되었으며 다른 개체에 대한 변경 사항에 대한 알림을 받도록 등록 할 수 있습니다. 다음을 수행하여 관심사를 등록합니다.

void*    gMyKVOContext = &gMyKVOContext; // global variable somewhere that guarantees us a unique address that doesn't collide with a subclass's registration for observing the same property

...

[interestingObject addObserver: interestedObject forKeyPath: @"interestingProperty" options: 0 context: gMyKVOContext];

해당 속성이 변경 될 때마다 관찰자로 지정한 개체에서 -observeValueForKeyPath : ofObject : change : context :가 호출됩니다. 따라서 다음과 같이 구현합니다.

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if( context == gMyKVOContext && [keyPath isEqualToString: @"interestingProperty"] )
    {
        // Update UI that shows interestingProperty
    }
    else
        [super observeValueForKeyPath: keyPath ofObject: object change: change context: context];
}

여기서 장점은 다른 속성이 변경되는 순간 라이브로 호출된다는 것입니다. 개체가 약간의 작업을 수행해야 이러한 알림이 전송되므로 모든 속성이 키-값을 관찰 할 수있는 것은 아닙니다. 또한 두 개의 관련 속성이 차례로 변경되면 일부 개체가 잘못된 상태에있을 수 있습니다. 첫 번째 속성이 변경된 후 알림을받습니다. 이제 두 번째 속성과 모순되고 두 번째 속성 만 변경되고 다시 알림을 받았습니다. 따라서 첫 번째 관찰자 콜백 동안 개체가 이상한 상태에있을 수 있으므로 이에 대한 반응에주의해야합니다.

속성을 관찰 가능하게 만들려면 정의 할 때 기본 @synthesized 구현을 사용하거나 직접 정의하는 경우 다음과 같이 setter를 구현합니다.

-(void)  setFoo: (int)inFoo
{
    [self willChangeValueForKey: @"foo"];
    _foo = inFoo;
    [self didChangeValueForKey: @"foo"];
}

그런 다음 항상 setter를 통해 변경하고 _foo를 직접 변경하지 마십시오. 위와 같이 서로 모순 될 수있는 관련 속성이있는 경우이를 방지하는 좋은 방법은 항상 두 항목을 쌍으로 변경하는 것입니다 (하지만 KVC를 사용할 수는 없습니다). 이를 위해 다음과 같이 결합 된 setter를 구현합니다.

-(void) setFoo: (int)inFoo bar: (int)inBar
{
    [self willChangeValueForKey: @"foo"];
    [self willChangeValueForKey: @"bar"];
    _foo = inFoo;
    _bar = inBar;
    [self didChangeValueForKey: @"bar"];
    [self didChangeValueForKey: @"foo"];
}

이렇게하면 속성이 적절한 상태에있는 동안 두 알림이 모두 전송됩니다.


여기서 시작하세요.

키-값 코딩은 접근 자 메서드를 호출하거나 인스턴스 변수를 통해 직접 액세스하는 대신 문자열을 사용하여 속성을 식별하여 객체의 속성에 간접적으로 액세스하는 메커니즘입니다.

참고URL : https://stackoverflow.com/questions/4282493/what-is-key-value-coding-and-key-value-observing-in-objective-c

반응형