Как включить новые литералы объекта 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
прежде чем объяснить, как добавить их только к соответствующим объектам. Оглядываясь назад, я считаю, что это была ошибка с моей стороны; это приводило к ошибкам, обнаруживаемым во время выполнения, а не во время компиляции, в отличие от подхода, представленного здесь. Этот подход все еще есть в моем блоге, но сейчас я считаю, что это скорее крутой взлом, чем полезный подход.
Источник: