Есть ли способ получить удобную функцию индексирования литералов Objective-C в Xcode 4.4?
Я прочитал все о новых литералах Objective-C и использовал XCode для преобразования моего старого кода, но код индексации не изменился. Я изменил это вручную, но тогда это не скомпилируется. Я видел пост, в котором говорилось, что нам нужно подождать до iOS 6, но я хочу, чтобы индексирование СЕЙЧАС!
Есть ли решение?
1 ответ
Ну, есть способ сделать это! Добавьте методы индексации в качестве категории к NSArray и NSDictionary, и вы сможете получить эту функцию для большинства классов, для которых она вам нужна. Вы можете прочитать о литералах ObjectiveC здесь. А благодаря решению Джеймса Вебстера для @YES и @NO вы можете использовать их в своих проектах и сейчас! (техника)
1) Создайте файлы интерфейса
// NSArray+Indexing.h
#if !defined(__IPHONE_6_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
@interface NSArray (Indexing)
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
@end
@interface NSMutableArray (Indexing)
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
@end
// NSDictionary+Indexing.h
@interface NSDictionary (Indexing)
- (id)objectForKeyedSubscript:(id)key;
@end
@interface NSMutableDictionary (Indexing)
- (void)setObject:(id)obj forKeyedSubscript:(id)key;
@end
#endif
2) Создайте файлы Реализации // см. Редактирование ниже, прежде чем делать это - вы можете пропустить это
// NSArray+Indexing.m
#if !defined(__IPHONE_6_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
#import "NSArray+Indexing.h"
@implementation NSArray (Indexing)
- (id)objectAtIndexedSubscript:(NSUInteger)idx
{
return [self objectAtIndex:idx];
}
@end
@implementation NSMutableArray (Indexing)
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx
{
[self replaceObjectAtIndex:idx withObject:obj];
}
@end
// NSMutableDictionary+Indexing.m
@implementation NSDictionary (Indexing)
- (id)objectForKeyedSubscript:(id)key
{
return [self objectForKey:key];
}
@end
@implementation NSMutableDictionary (Indexing)
- (void)setObject:(id)obj forKeyedSubscript:(id)key
{
[self setObject:obj forKey:key];
}
@end
#endif
3) Добавьте файлы интерфейса в ваш файл pch для глобального использования или добавьте их по мере необходимости в файлы.m
// Add to PCH file
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
...
#if !defined(__IPHONE_6_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
// New Indexing
#import "NSDictionary+Indexing.h"
#import "NSArray+Indexing.h"
// Provided by James Webster on StackOverFlow
#if __has_feature(objc_bool)
#undef YES
#undef NO
#define YES __objc_yes
#define NO __objc_no
#endif
#endif
#endif
#endif
4) Перестройте, затем добавьте следующие файлы, чтобы убедиться, что все работает
// Test Example
{
NSMutableArray *a = [NSMutableArray arrayWithArray:@[ @"a", @"b", @"c" ]];
NSLog(@"%@", a[1]);
a[1] = @"foo";
NSLog(@"a: %@", a);
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:@{ @"key" : @"object" }];
NSLog(@"%@", dict[@"key"]);
dict[@"key"] = @"New Object";
dict[@"newKey"] = @"WOW a new object";
NSLog(@"dict: %@", dict);
NSLog(@" %@ %@", @YES, @NO );
}
РЕДАКТИРОВАТЬ: Ну, в соответствии с ключевым инженером Apple llvm / clang, есть библиотека, которая уже связана с реализациями, так что вам просто нужен файл интерфейса:
Дата: Пн, 20 августа 2012 15:16:43 -0700 От: Грег Паркер Кому: ... Тема: Re: Как заставить подписку на Obj-C работать на iOS 5? ...
В качестве эксперимента я добавил категорию @interface для этих методов, но не @implementation - приложение все еще работало нормально (по крайней мере, в симуляторе 5.1)
Компилятор испускает те же вызовы. Волшебство заключается во все более неточно названном libarclite ("Это не только для ARC Anymore™"), который добавляет реализации методов подписки во время выполнения, если они еще не существуют.
В IIRC есть некоторые классы с поддержкой индексов, которые libarclite не обновляет (возможно, NSOrderedSet?), Поэтому вам все равно нужно тщательно протестировать старые цели развертывания.