Есть ли способ получить удобную функцию индексирования литералов 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?), Поэтому вам все равно нужно тщательно протестировать старые цели развертывания.

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