키 값 코딩을 사용하여 개체에 대한 키가 존재하는지 어떻게 알 수 있습니까?

StackOverflow https://stackoverflow.com/questions/1868708

문제

객체에 iPhone SDK에 Writeable @Property가 있는지 테스트하고 싶습니다.

이 작업을 수행하는 한 가지 방법 중 하나는 -valueforkey : method를 확인하는 것이지만 다소 부적절 해 보입니다!

예시:

  @try {
    id *value = [instance valueForKey:@"myProperty"];
  }
  @catch (NSException * e) {
    // Key did not exist
  }

더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

확인중인 객체를 만들면 재정의 할 수 있습니다. valueForUndefinedKey: 그리고 setValue:forUndefinedKey 예외를 제기하는 것보다 더 유용한 일을합니다.

반면에, 런타임에서 알지 못하는 객체를 내성적으로 지정하려고한다면 런타임 메소드를 사용하여이를 수행해야합니다. Objective-C 런타임 자체를 사용하고 class_copyPropertyList 또는 protocol_copyPropertyList 그리고 그것들을 다루거나 기초를 사용하고 전화하십시오. respondsToSelector 주어진 속성에 대한 KVC getter/setters의 개체, 예를 들어, 재산에 대한 foo 당신은 같은 것을 부를 것입니다 [someObject respondsToSelector:NSSelectorFromString(@"foo")];.

다른 팁

일반적으로 객체에 주어진 키에 대한 값이 있는지 확인할 방법은 없습니다. 인스턴스는 그 정의되지 않은 키에 대한 값을 반환하기로 결정할 수 있습니다. -valueForUndefinedKey: 방법. 또는 기본 구현에 예외가 발생할 수 있습니다. 현대 대상 C (2.0) 객체 자주 공개 API의 관련 속성을 선언하십시오. 이러한 개체의 경우 Objective-C 런타임을 사용할 수 있습니다. class_copyPropertyList 또는 protocol_copyPropertyList 사용 가능한 속성 목록을 얻으려면 또한 KVC 검색 목록을 모방 할 수도 있습니다. repondsToSelector: 인스턴스가 적절한 getter 메소드에 응답하는 경우 마지막으로 런타임을 사용할 수 있습니다 class_copyIvarList 적절한 IVAR이 Ivars를 점검하려면. 이것은 많은 당신이 일하는 일 하지 말아야합니다. 객체 인스턴스가 보낸시 예외가 발생하는지 여부를 알지 못하는 것은 아닙니다. valueForKey: 메시지와 그것은 더 큰 문제를 나타냅니다 ...

주어진 키에 대한 값을 모두 제공 해야하는 객체 모음이 있지만 일부는 그렇지 않으면 디자인 문제가 있습니다. 적절한 인터페이스를 정의해야합니다 (a @protocol 대상 c)에서 필요한 속성을 선언합니다. 그런 다음이 프로토콜을 준수하거나 컴파일러를 사용하여 인스턴스가 프로토콜을 준수하는 경우 (단일 인스턴스를 전달하는 경우) 컴파일 타임 유형 확인을 수행 할 수 있습니다.

@Jason Coco 답변에서 다음.

다음은 설정하려는 속성의 "Set"Selectors가 있는지 특별히 확인하는 방법에 대한 제 제안입니다.

이것은 순수한 오물이지만 효과가 있고 나는 그것을 사용하는 것을 발견했습니다. 당신은 경고를 받았습니다 ..

NS_INLINE SEL _Nonnull IBPropertySetSelectorForPropertyName(NSString*_Nonnull propertyName)
{

    NSString* firstLetter = [propertyName substringToIndex:1];
    propertyName = [propertyName substringFromIndex:1];

    propertyName = [[NSString alloc] initWithFormat:@"set%@%@:",firstLetter.capitalizedString,propertyName];

    return NSSelectorFromString(propertyName);
}

용법:

Swift에서 : 브리징 헤더에 코드 스 니펫을 추가 한 다음 :

let key = "someKey"    
let sel = IBPropertySetSelectorForPropertyName(key)

if SOMETHING.responds(to: sel) {SOMETHING.setValue(value, forKeyPath: key)}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top