2012-01-09 3 views
1

나는 엑스 코드는 내가 예외 만 발생되는 것을 발견을 디버깅하려고하면이 코드allKeys를 사용할 때 응용 프로그램이 충돌합니다. 객체가 하나뿐이기 때문입니까?

NSDictionary *nextArray = [_classDictionary 
valueForKeyPath:@"response.page_records.page_record"]; 
for (NSDictionary *roster2 in nextArray) { 
NSArray *keys = [roster2 allKeys]; 
if ([keys containsObject:@"title"]){ 
    [pageName addObject:[roster2 objectForKey:@"title"]]; 
} 
if ([keys containsObject:@"id"]) { 
[pageID addObject:[roster2 objectForKey:@"id"]]; 
} 
} 

를 사용할 때마다이 오류를

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-  
[__NSCFString allKeys]: unrecognized selector sent to instance 0x9367330' 

을 던져 계속 이유를 알 수없는 경우가 키의 객체는 하나뿐입니다.

(
{ 
    "class_id" = 0001; 
    "id" = 1234; 
    "title" = "First Page"; 
}, 
{ 
    "class_id" = 0002; 
    "id" = 12345; 
    "title" = Assignments; 
} 
) 

코드가 예외없이 실행되지만 코드는 단순히

 { 
     "class_id" = 0001; 
     "id" = 1234; 
     "title" = "First Page"; 
    } 

때 예외가 발생합니다 : 예를 들어 "nextArray은"이 때. 왜 이런 일이 일어날까요? 객체가 하나만있는 경우에도 키에는 객체 제목이 포함됩니다. 이 예외가 던져지고있는 다른 모든 아이디어? 괄호와 관련이 있습니까? (전체 추측) 실제로 진행되고있는 것을 디버깅하는 더 좋은 방법이 있습니까?

편집 : 여기에 _userDictionary가 있습니다. objectforKey : @ "title"의 정렬 된 배열을 갖고 위의 오류를 피하는 가장 좋은 방법은 무엇입니까? NSStringallKeys에 응답하지 않기 때문에

response =  { 
    "status" = ok; 
    "page_records" =   { 
     "page" = 1; 
     "page_count" = 1; 
     "records_per_page" = 50; 
     "total_record_count" = 2; 
     "page_record" =    (
          { 
       "class_id" = 0001; 
       "id" = 1234; 
       "title" = "Test page"; 
      }, 
          { 
       "class_id" = 0002; 
       "id" = 12345; 
       "title" = "testing page 2"; 
      } 
     ); 
    }; 
}; 
} 
+0

좋아, 내가 왜 이런 일이 일어나고 있는지에 대한 진전을 보이고있다. 나는 해결책이 없다. 하나의 "제목"만있는 데이터가 NSArray로 처리되고 NSArray에 allKeys 선택자가 없기 때문에 그럴까요? – davis

+0

아니, 그 NSString에 전화하려고 노력하고있다 – DanZimm

+0

사전을 추가, 내 objectofKey 얻을 수있는 내 코드에 대한 대안이있다 : ""제목과 위의 오류를 피하기? – davis

답변

3

, 당신은 사전의 배열을 반복하고 있으며, 따라서, NSArray *keys = [roster2 allKeys];는 배열에 호출되고. 그러나 두 번째 예에서는 하나만 사전이 있습니다. 아니요 사전 배열입니다. 따라서 루프 for (NSDictionary *roster2 in nextArray)은 배열이 아닌 문자열 인 사전의 키를 반복합니다. 따라서 오류.

우선, 귀하의 이름이 혼란 스럽습니다. NSDictionarynextArray?이 시도 : 그것은 당신이 NSString의 인스턴스에 방법 allKeys를 호출 위해 노력하고 있다는 것을 의미

[__NSCFString allKeys]: unrecognized selector 

:

id *response = [_classDictionary valueForKeyPath:@"response.page_records.page_record"]; 
NSMutableArray *records; 

if ([response isKindOfClass: [NSDictionary class]]) { 
    records = [[NSMutableArray alloc] init]; 
    [records addObject: response]; 
} 
else { 
    records = [NSMutableArray arrayWithArray: response]; 
} 

for (NSDictionary *roster2 in records) { 
    NSArray *keys = [roster2 allKeys]; 
    if ([keys containsObject:@"title"]){ 
     [pageName addObject:[roster2 objectForKey:@"title"]]; 
    } 
    if ([keys containsObject:@"id"]) { 
     [pageID addObject:[roster2 objectForKey:@"id"]]; 
    } 
} 
+0

좋습니다. 그렇기 때문에 해결책이 있습니까? 내 NSDictionary _classDictionary는 변환 된 XML 데이터입니다. 내가 원하는 건 그 키에 대해 하나의 객체 만있는 경우에도 "titles"객체의 정렬 된 배열입니다. – davis

+0

_classDictionary를 추가했습니다. 이 오류를 피하기 위해 코드를 어떻게 변경해야하는지 제안 해주십시오. – davis

+0

내 답변이 업데이트되었습니다. – john

0

아니, 그건. 콘솔 로그는 이것을 알려주므로 좀 더주의 깊게 읽어야합니다.

NeXT 스타일 plists에서 ({})은 사전이 포함 된 배열을 정의합니다. {}을 단지 사전으로 정의합니다. 즉,이,이다 : 그들은 같은 정보를 포함하더라도

(
    { 
     "class_id" = 0001; 
     "id" = 1234; 
     "title" = "First Page"; 
    } 
) 

:

{ 
    "class_id" = 0001; 
    "id" = 1234; 
    "title" = "First Page"; 
} 

하지 구조적으로이 동일합니다. 루트 배열에 하나의 요소 만있는 경우에도 배열이 있다는 것을 plist 파서에 알려야하므로 논리를 올바르게 처리하려면 ()을 포함해야합니다.

편집 : 귀하의 의견에 정보가 주어지면 솔루션은 그리 간단하지 않습니다. 소스 데이터가 이와 같이 임의적 인 경우 데이터 형식이 NSArray 또는 NSDictionary인지 확인하고 적절하게 처리해야합니다. 예를 들어 첫 번째 예에서

id myData = [self plistFromArbitrarySource]; 
if (myData) { 
    if ([myData isKindOfClass: [NSArray class]]) { 
     for (NSDictionary *dict in myData) { 
      [self parseDictionary:dict]; 
     } 
    } else if ([myData isKindOfClass: [NSDictionary class]]) { 
     [self parseDictionary:myData]; 
    } 
} 
+0

그래서 XMLReader 플러그인을 사용하여 XML을 NSDictionary로 변환합니다. 변환 된 NSDictionary "_classDictionary"에는 괄호가 없습니다. valueForKeyPath를 사용할 때 해당 키 경로에 둘 이상의 값이있을 때 괄호가 삽입됩니다. 키 경로에 단 하나의 값만있을 때 괄호를 추가해야 할 필요가있는 것 같습니다. 무슨 일이 일어나고 있는지 이해하고 있습니까? – davis

+0

_classDictionary를 추가했습니다. 이 오류를 피하기 위해이 코드를 어떻게 변경해야하는지 제안 해주십시오. – davis

+0

괄호는 * array *, *** ***이 아닌 사전을 나타냅니다. 그것들은 다른 데이터 구조입니다. –

0

오류 메시지가 당신이 알아야 할 모든이 포함되어 있습니다.

의 당신이 allKeys를 호출 할 경우를 살펴 보자 :

for (NSDictionary *roster2 in nextArray) { 
    NSArray *keys = [roster2 allKeys]; 

roster2이있는 NSString의 인스턴스가 아닌있는 NSDictionary이다. nextArrayNSDictionary 개체가 포함될 것으로 예상되지만 대신 NSString 개체가 포함되어 있습니다.

+0

_classDictionary를 추가했습니다. 'valueForKey : @ "title"'을 얻기 위해 코드를 변경하는 방법을 제안하고이 오류를 피할 수 있습니까? – davis

관련 문제