2012-06-11 3 views
1

내 자신의 개체 컬렉션을 NSDictionary (JSON 용)로 깊이 파싱하려고합니다.ObjC valueForKey가 NSNumber 또는 UDT에 대해 작동하지 않습니다.

나는 나의 모델의 모든 연장 기본 객체 클래스를 가지고 있고, 차례로이 baseobject는 NSObject의 확장 : 방법에있어서

@interface BaseObj : NSObject <DICTMaker> 
    - (NSMutableDictionary *) toDICT; 
@end 

을, 나는 목록을 가져올 수 objc-런타임을 사용 속성의. [self valueForKey:]을 사용하는 것에 대한 참조를 얻을 수있는 모든 속성은 내 사전에 속성의 이름과 값을 삽입합니다.

그러나 내가 지금까지 알아 차린 것은 NSNumber과 사용자 정의 클래스가 사전에 추가되지 않는다는 것입니다. 내 파서가 가장 확실하게 식별합니다. 로그에 모든 것을 뱉어 내기 때문입니다. [self valueForKey:]은 모두 NSNumbers 및 사용자 정의 개체에 nil을 반환합니다. 그 결과 사전은 이메일, 비밀번호, password_confirm에 대한 항목을 포함

@interface UserRegistrationLocation : BaseObj { 
    NSString *address, *street, *street_2, *city; 
    NSNumber *addr_state, *addr_zip; 
} 

@interface UserRegistrationContact : BaseObj { 
    NSString *first_name, *last_name; 
    NSString *p_phone_area, *p_phone_first_3, *p_phone_last_4; 
    NSString *s_phone_area, *s_phone_first_3, *s_phone_last_4; 
} 

@interface UserRegistration : BaseObj { 
    NSString *email, *password, *password_confirm; 
    NSNumber *referral; 

    UserRegistrationContact *primary, *secondary; 
    UserRegistrationLocation *address; 
} 

NSMutableDictionary *mydict = [myUserRegistration toDICT]; 

: 여기

- (NSMutableDictionary *)toDICT { 
    NSMutableDictionary *props = [NSMutableDictionary dictionary]; 
    unsigned int outCount, i; 
    objc_property_t *properties = class_copyPropertyList([self class], &outCount); 
    for (i = 0; i < outCount; i++) { 
     objc_property_t property = properties[i]; 

     // Both of these work, I promise: 
     NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)]; 
     NSString *propertyType = [NSString stringWithUTF8String:getPropertyType(property)]; 

     NSLog(@"%@ of Type: %@", propertyName, propertyType); 
     id propertyValue = [self valueForKey:propertyName]; 
     if ([ propertyValue respondsToSelector:@selector(toDICT:) ]) 
      [ props setObject:[propertyValue toDICT] forKey:propertyName ]; 
     else if (propertyValue) 
      [ props setObject:propertyValue forKey:propertyName ]; 
     else 
      NSLog(@"Unable to get ref to: %@", propertyName); 
    } 
    free(properties); 
    return props; 
} 

내가 만든 던져 샘플 개체입니다

[11012:f803] Unable to get ref to: referral 
[11012:f803] Unable to get ref to: primary 
[11012:f803] Unable to get ref to: secondary 
[11012:f803] Unable to get ref to: address 
[11012:f803] {"user":{"password":"haxme123","password_confirm":"haxme123","email":"[email protected]"}} 

모든 지원하시기 바랍니다 = }!

답변

1

어쩌면 내가 문제를 잘못 이해했는지 모르겠지만 귀하의 추천, 기본 및 그래서 단순히 null이 아닌가요? 키 값 저장소에 없으면 예외가 발생합니다. 그 밖의 부분은 keyvalue 저장소에 속성이 있지만 nil이 할당 된 경우에만 호출됩니다. 최소한 예제 코드에서 값을 설정하면 결정할 수 없습니다. (널) 가 심판을 가져올 수 없습니다 : 가치와 시험 인 aNumber : 5

테스트가 null과 의지 나는 아래의 코드로 예를 줄일 경우

, 나는 값으로 다음과 같은 출력 테스트를 얻을 당신의 메시지를 "할 수 없다". 번호가 정확합니다. 테스트를 일부 텍스트로 변경하면 "불가능 ..."부분이 사라집니다. copyPropertyList는 속성 만 복사하기 때문에 속성이 아닌 추가 멤버 변수 _noProp은 여기에서 발생하지 않습니다.

@interface TestValueForKey : NSObject { 
    NSString* _test; 
    NSString* _noProp; 
    NSNumber* _aNumber; 
} 

@property (retain) NSString* test; 
@property (retain) NSNumber* aNumber; 

-(void)myTest; 

@implementation TestValueForKey 

@synthesize test = _test; 
@synthesize aNumber = _aNumber; 

-(id)init 
{ 
    if((self = [super init]) != nil) { 
     _test = nil; 
     _aNumber = [NSNumber numberWithInt:5]; 
    } 

    return self; 
} 

-(void)myTest 
{ 
    NSMutableDictionary *props = [NSMutableDictionary dictionary]; 
    unsigned int outCount, i; 
    objc_property_t *properties = class_copyPropertyList([self class], &outCount); 
    for(i = 0; i < outCount; i++) { 
     objc_property_t property = properties[i]; 

     // Both of these work, I promise: 
     NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)]; 

     id propertyValue = [self valueForKey:propertyName]; 
     NSLog(@"%@ with Value: %@", propertyName, propertyValue); 
     if (propertyValue) 
      [ props setObject:propertyValue forKey:propertyName ]; 
     else 
      NSLog(@"Unable to get ref to: %@", propertyName); 
    } 
    free(properties); 
} 
@end 
+0

얼마나 내 당황스럽고 내면의 물체에 데이터가 할당 되었는가.그러나 클래스 자체가 제대로 초기화되지 않았습니다! -10 프로그래머 pnts –

2

속성 값이 아닌 ivars 만 선언했습니다. class_copyPropertyList@property 선언이 필요합니다. class_getInstanceVariable과 같은 ivar 액세스 함수를 사용할 수 있습니다.

그러나이 접근법은 너무 영리 해 지려고합니다. 예를 들어 -(NSArray *)keysForJSONSerialization과 같이 직렬화 할 키 배열을 반환하는 메서드를 구현할 것입니다. 이는 의도를보다 명확하게 나타내며 특정 속성의 직렬화를 방지 할 수 있습니다 (어느 시점에서 원할 것으로 의심됩니다).

+0

로그에 이름이 나타나기 때문에 속성 선언이 표시되지 않았다고 가정했습니다. +1 두 번째 단락의 경우 – jrturton

+0

jrtuton이 제안 했으므로 위의 목록에서 단순화하기 위해 제거되었지만 해당 '@ property' 및'@ synthesize' 선언이 실제로 존재했습니다. 그래도 돈이 없다. –

관련 문제