2012-12-06 5 views
1

저는 iOS/Objective C에 매우 익숙하지만 여러 언어로 여러 해 동안 프로그래밍 해왔습니다.plist를로드 할 때 배열 첨자가 정수가 아닙니다.

저희 회사는 기존 iOS 응용 프로그램을 수정했습니다. 지금 plist 파일을로드하고 그 내용으로 UITableView 채 웁니다. 내 코드를 사용하여 셀을 만드는 동안 오류가 발생하며 어떤 일이 일어나는지 잘 모르겠습니다.

여기에, 아주 간단한 내 PLIST 파일입니다

여기
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
    <array> 
     <dict> 
      <key>title</key><string>Un</string> 
      <key>subtitle</key><string>Subtitle</string> 
     </dict> 
     <dict> 
      <key>title</key><string>Deux</string> 
      <key>subtitle</key><string>Subtitle</string> 
     </dict> 
    </array> 
</plist> 

내가 메모리에 PLIST 파일을로드 어디에 :

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSString *plistCatPath = [[NSBundle mainBundle] pathForResource:@"resources" ofType:@"plist"]; 
    resources = [NSMutableArray arrayWithContentsOfFile:plistCatPath]; 
} 

을 그리고 여기에 내가 속성에 액세스하려고 곳입니다. 이것은 분명히 새 객체 리터럴 구문을 인식하지 못하는 오래된 컴파일러를 사용하고 있기 때문에

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    int index = (int) indexPath.row; 
    UITableViewCell *cell =[factory cellOfKind:@"cell" forTable:tableView]; 
    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; 
    UILabel *lblTitle = (UILabel*)[cell viewWithTag:2]; 
    UILabel *lblSubtitle = (UILabel*)[cell viewWithTag:3]; 
    NSDictionary *resource = resources[index]; // incompatible types in initialization 
    NSString *row_title = resource[@"title"]; // array subscript is not an integer 
    NSString *row_subtitle = resource[@"subtitle"]; // array subscript is not an integer 
    [lblTitle setText: row_title]; 
    [lblSubtitle setText: row_subtitle]; 
    return cell; 
} 
+0

최신 버전의 'clang'을 사용하고 있습니까? GCC와 오래된 Clang은이 구조를 인식하지 못합니다. –

+0

@ H2CO3 나는 거의 긍정적이다. 기존 프로젝트의 이전 소스 코드와 10.6.8이있는 Mac에만 액세스 할 수 있기 때문에 Xcode 3.2.6을 실행하고 iOS 4.2 용으로 컴파일하고 있습니다. 나는 그것이 필요하지 않다면 이것의 일부 또는 전부를 업그레이드하는 것을 저항 해왔다. "다른 구조"(가능하다면)를 추천하거나 다른 이유로 다른 곳으로 업그레이드해야 할 필요가 있습니까? – raydowe

+0

또 다른 구조가 있습니다. 제 답변을 참조하십시오. –

답변

2

H2CO3이 말한 것처럼이 구문은 Xcode 4.4 및 4.5와 함께 릴리스 된 "Modern Objective-C"의 일부인 오브젝트 하위 스크립팅의 일부입니다.

숫자가 아닌 숫자에 대한 설명은 Objective-C Literals 사이트를 방문하여 "구독 방식"(Apple에서 "boxing syntax"또는 "boxed syntax"라고 부르는 경우도 있음) 섹션으로 스크롤하면 거기에서 논의 된 것을보십시오. 나는 내 대답의 맨 아래에 다른 참고 문헌을 포함시켰다.

첫 번째 예는, 배열의 값을 찾기위한, 배열 스타일의 첨자입니다 :

NSDictionary *resource = [resources objectAtIndexedSubscript:index]; 

것은 원하지 않는 경우

NSArray *resources = ... // however it was defined 
NSDictionary *resource = resources[index]; 

컴파일러는이 변환 컴퓨터에서 Xcode (및 컴파일러)를 업그레이드하려면 배열 형식의 서브 스크립트를 기존의 objectAtIndex 구문으로 바꿀 수 있습니다 :

NSDictionary *resource = [resources objectAtIndex:index]; 

마찬가지로, 우리에게 보여준 두 번째 예제는 숫자가 아닌 하위 첨자를 사용했습니다.이 사전 스타일의 첨자입니다 : 컴파일러가 번역됩니다

NSString *row_title = resource[@"title"]; 

: 당신이 당신의 엑스 코드 (및 컴파일러)를 업그레이드하지 않는 경우, 다시

NSString *row_title = [resource objectForKeyedSubscript:@"title"]; 

그리고, 기존의 것과 동일합니다 :

NSString *row_title = [resource objectForKey:@"title"]; 

결론은, 어쩌면 당신이 운이있을거야의 NSArray 및의 첨자의 사용은이 방법으로 제한됩니다. 그러나이 프로젝트는 "현대 오브젝티브 C"를 사용하는 리팩토링되었고, 당신은 배열 리터럴 같은 다른 현대 오브젝티브 C 구조, 볼 수 있습니다 : 당신이있는 경우

NSArray *array = @[@"one", @"two", @"three"]; 

을 그 어느 곳이 프로젝트에, 당신을

01,238,706,195,987,132,998 : 당신이 사전 리터럴를 볼 수 있습니다, 마찬가지로

NSArray *array = [NSArray arrayWithObjects:@"one", @"two", @"three", nil]; 

: 이전 컴파일러는 배열 리터럴 구문을 이해하지 않습니다, 당신은으로 교체해야합니다

NSNumber *number = @4; 
NSNumber *done = @YES; 

NSNumber *number = [NSNumber numberWithInt:4]; 
NSNumber *done = [NSNumber numberWithBool:YES]; 

동등하다는 : 마지막으로

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil]; 

, 당신은 예를 들어, 너무 숫자 리터럴을 가질 수있다 :

당신은 함께 있음을 바꿔야합니다 프로젝트의 현대 목표 (Modern Objective-C)가 얼마나 많은지에 따라, 당신이 수행해야 할 수도 있습니다. 또는 Xcode 4.5 이상으로 업그레이드 할 수 있다면 문제없이이 코드를 컴파일 할 수 있습니다. 당신은 WWDC에게 현대 오브젝티브 C 2012 세션을주의해야 등 새로운 NSDictionary 열거하는 방법, 입력 된 열거 형, 문자열 리터럴을 포함하여 엑스 코드 4.5에 꽤 많은 다른 매우 유용한 구조가있다

당신이 수 있도록 당신이 오래된 컴파일러를 고수함으로써 누락 된 것을 알고 또한 Stack Overflow 나 다른 곳에서 게시 된 Modern Objective-C 코드를 해독하는 방법을 알아낼 수 있습니다. 자세한 내용은

은 다음을 참조하십시오

+1

매우 철저한 설명에 감사드립니다. 하단의 링크는 이미 매우 도움이되는 것으로 입증되었습니다. – raydowe

1

: 내가 컴파일시에 오류를 받고 있어요 의견을 추가했습니다. 업그레이드하지 않으려면, NSArrayNSDictionary에서 해당 인스턴스 방법을 사용하십시오

NSDictionary *resource = [resources objectAtIndex:index]; 
NSString *row_title = [resource objectForKey:@"title"]; 
NSString *row_subtitle = [resource objectForKey:@"subtitle"]; 

이 방법을 선택하면, 당신은 좋은 하위 호환성을 유지합니다.

+0

감사합니다. 그래서 필자가 찾은 많은 예제 코드에서 구문에 문제가 있었는지 설명합니다. – raydowe

관련 문제