2012-07-25 10 views
23

Kiedy utworzyć nowy projekt z Xcode 4.4 i dodać te linie:Jak włączyć nowe znaki obiektowe Objective-C na iOS?

NSDictionary *test = @{ @"key" : @"test value" }; 
NSString *value = test[@"key"]; 
NSLog(@"value is: %@", value); 

kompiluje bez ostrzeżenia i wykonuje zgodnie z oczekiwaniami.

Dodając te same linie do istniejącego projektu powoduje błąd kompilatora:

NSString *value = test[@"key"]; <-- Expected method to read dictionary element not found on object of type 'NSDictionary *' 

Porównałem ustawienia kompilacji docelowych obu projektów, ale nic nie wyskoczyła na mnie.

Aktualizacja: Nowy projekt, który został pomyślnie skompilowany, był dla OSX. Próbowałem innego nowego dla iOS z powyższymi liniami i nie udało się go skompilować, tak jak mój wcześniejszy projekt (iOS).

+0

I oba projekty były przy użyciu szczęk 4.0? – trojanfoe

+0

@trojanfoe Oba używają "kompilatora Apple LLVM 4.0". – darrinm

+0

I oba target x86_64 (nie i386)? – trojanfoe

Odpowiedz

48

Nie ma to nic wspólnego z projektem starszym niż nowym, ale jest czynnikiem używanym przez SDK. Problem polega na tym, że podczas gdy jest to funkcja kompilatora, wymaga obsługi SDK. Pakiet SDK dla systemu iOS 5 nie zapewnia tej obsługi, mimo że działa na nim zestaw SDK iOS 6.

Z tego powodu należy teraz użyć zestawu SDK do systemu iOS 6. Czytaj dalej, jeśli chcesz korzystać z subskrybowania obiektów za pomocą zestawu SDK iOS 5.

Wszystko, co musisz zrobić, to dodać plik nagłówka, aby kompilator spróbował wykonać połączenie. Nie ma potrzeby dodawania implementacji; jest obsługiwany automatycznie przez arclite. (Jeśli nie używasz łuku, trzeba będzie zmusić łącznik obejmuje arclite. Ale nadal nie mają faktycznie na niego przełączyć.)

Utwórz nowy plik interfejsu NSObject + subscripts.h .

#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000 
@interface NSDictionary(subscripts) 
- (id)objectForKeyedSubscript:(id)key; 
@end 

@interface NSMutableDictionary(subscripts) 
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key; 
@end 

@interface NSArray(subscripts) 
- (id)objectAtIndexedSubscript:(NSUInteger)idx; 
@end 

@interface NSMutableArray(subscripts) 
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx; 
@end 
#endif 

Położyłem ten kawałek na github.

Uwaga: Sugerowałem dodanie wymaganych metod do NSObject przed wyjaśnieniem, jak dodać je tylko do odpowiednich obiektów. Z perspektywy czasu uważam, że był to błąd z mojej strony; Doprowadziło to do błędów wychwytywanych w środowisku wykonawczym, a nie w czasie kompilacji, w przeciwieństwie do przedstawionego tutaj podejścia. To podejście wciąż jest na moim blog, ale teraz uważam, że jest to bardziej fajne hakowanie niż użyteczne podejście.

Źródło:

+0

To wykonało zadanie dla mnie, dzięki! Wszystko będzie dobrze, dopóki Xcode 4.5 nie zostanie dostarczony z oficjalną obsługą iOS. – darrinm

+0

Dodałem go tylko na NSDictionary/NSArray i zaimplementowałem w celu wywołania zwykłych metod. Działa dobrze (to ios 6 robi tak). – borrrden

+0

Nie potrzebujesz @ implementacji. Ale tak, dzisiaj nie miałem problemu z dodaniem tylko kategorii, których potrzebowałem do klas, które chciałem. Zaktualizuję odpowiedź. –

Powiązane problemy