2012-01-25 2 views
4

현재 개체 (NSManagedObject)의 속성이 있는지 여부를 확인하기 위해 문제가 발생했습니다.Objective C - respondsToSelector for dynamic properties

불행하게도 방법

[[MyObject class] respondsToSelector:@selector(myProperty)]; 

항상 NO를 반환합니다.

나는 CoreData에 의해 생성 된 속성이 그래서 어떤 아이디어는 어떻게이 문제를 해결하기

@property (nonatomic, strong) NSString *myProperty 

ALA 새로운 스타일 속성이 있기 때문에 그것을 생각? 사전에)

감사합니다,

난 정말 당신의 제안을 모두 감사하겠습니다! 알렉스

답변

14

는 메타 객체가 해당 선택자에 응답하는지 여부를 묻습니다. 따라서 실제로 해당 선택기가있는 클래스 메서드가 있는지 여부를 묻습니다. 당신이 있다면 코드는 YES 반환하지 않을 것이다 : 당신은 당신의 클래스의 인스턴스에 respondsToSelector:를 호출 할 필요가

- (NSString *)myProperty; 

: 인스턴스 메소드의 상당을 가지고 있기 때문에

+ (NSString *)myProperty; 

은 NO 반환합니다.

일반적으로 instancesRespondToSelector:을 메타 클래스 (예 : [MyObject instancesRespondToSelector:...])에 직접 사용할 수 있지만 코어 데이터는 개체를 만들 때만 관련 메서드 구현을 합성하므로 비 스타터입니다. 그러나 보통 NSEntityDescription 경로를 통해 인스턴스를 생성하고 respondsToSelector:을 테스트 할 수 있습니다. 이 모든 핵심 데이터의 이후

은, 대안은 entitiesByName 사전을 통해 관련 NSEntityDescription에 대한 NSManagedObjectModel을 물어 엔티티 설명의 propertiesByName 사전을 검사하는 것입니다.

+1

더 나은 답변 ... 내 것을 삭제하겠습니다! – jrturton

+0

좋아요,하지만 문제는, 제가 테스트하고 싶은 시점에 인스턴스 객체가 없다는 것입니다 ... 그래서 다른 가능성이 있습니까? – Alexander

+1

당신은 보통'instancesRespondToSelector :'를'MyObject'에 직접 사용합니다. 그러나 Core Data의 내부 구조는이 경우 비 스타터가됩니다.그래서 당신은 인스턴스를주고, 보통의'respondsToSelector :'를 수행 한 다음 영구적 인 저장소에 객체를 추가하는 대신 객체를 버리는 코어 데이터를 얻을 필요가 있습니다. – Tommy

0

클래스 파일에서 속성을 합성하고 있습니까?

@interface SomeClass : NSObject 
{ 
    @property (nonatomic, strong) NSString *myProperty 
} 
@end 


@implementation SomeClass 

    @synthesize myProperty; 

@end 
+0

CoreData의 생성 된 파일을 사용하여 소품이 @ 동적 인 경우 Tommy가 대답을 줄 수 있습니다.) – Alexander

1

필자가 필자가 요구 한 유일한 경우는 물건을 동적으로 설정하는 것이기 때문에 나는 세터만을 찾고있다. 나는 setter에 대한 서명을 작성한 다음 존재하는지 테스트 한 다음이를 사용하고있다.

NSArray * keys = [myObject allKeys]; 
for(NSString * key in keys) 
{ 
    NSString * string = [NSString stringWithFormat:@"set%@:", [key capitalizedString]]; 
    SEL selector = NSSelectorFromString(string); 
    if([myObject respondsToSelector:selector] == YES) 
    { 
     id object = [dict objectForKey:key]; 

     // To massage the compiler's warnings avoid performSelector 
     IMP imp = [card methodForSelector:selector]; 
     void (*method)(id, SEL, id) = (void *)imp; 
     method(myObject, selector, object); 
    } 
} 

이 코드는 사전에받은 모든 데이터를 소화하지 않을 수도있는 필요를 충족시킵니다. 이 경우에는 json이 희박하므로 일부 데이터가 json에 항상 존재하지 않을 수 있으므로 해당 키를 찾는 myObjects 속성을 단계별로 실행하면 많은 노력이 낭비됩니다.