Как включить новые литералы объекта Objective-C на iOS?

Когда я создаю новый проект с Xcode 4.4 и добавляю эти строки:

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

он компилируется без предупреждений и выполняется как ожидалось.

Добавление тех же строк в существующий проект приводит к ошибке компилятора:

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

Я сравнил настройки целевой сборки обоих проектов, но ничего не выпрыгнуло на меня.

Обновление: новый успешно скомпилированный проект для OSX. Я попробовал другой новый для iOS с вышеуказанными строками, и он не может скомпилироваться, так же, как мой ранее существовавший (iOS) проект.

1 ответ

Решение

Это не имеет ничего общего со старым или новым проектом, а скорее является фактором используемого вами SDK. Проблема, с которой вы сталкиваетесь, заключается в том, что, хотя это функция компилятора, она требует поддержки SDK. IOS 5 SDK не обеспечивает такую ​​поддержку, хотя iOS 6 SDK делает.

По этой причине, теперь вы должны просто использовать iOS 6 SDK. Читайте дальше, если вы хотите использовать подписку на объекты с помощью iOS 5 SDK.

Все, что вам нужно сделать, это добавить файл заголовка, чтобы компилятор попытался выполнить вызов. Нет необходимости добавлять реализацию; он обрабатывается автоматически arclite, (Если вы не используете ARC, вам придется заставить компоновщик включить arclite, Но вам все равно не обязательно переключаться на него.)

Создайте новый файл интерфейса, 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

Я положил этот кусок на GitHub.

Примечание: я предлагал добавить необходимые методы в NSObject прежде чем объяснить, как добавить их только к соответствующим объектам. Оглядываясь назад, я считаю, что это была ошибка с моей стороны; это приводило к ошибкам, обнаруживаемым во время выполнения, а не во время компиляции, в отличие от подхода, представленного здесь. Этот подход все еще есть в моем блоге, но сейчас я считаю, что это скорее крутой взлом, чем полезный подход.

Источник:

Другие вопросы по тегам