我阅读了有关新的 Objective-C 文字的所有信息,并使用 Xcode 转换了我的旧代码,但索引代码没有改变。我手动更改了它,但它不会编译。我看到一个帖子说我们必须等到 iOS 6,但我现在想要索引!
有什么解决办法吗?
我阅读了有关新的 Objective-C 文字的所有信息,并使用 Xcode 转换了我的旧代码,但索引代码没有改变。我手动更改了它,但它不会编译。我看到一个帖子说我们必须等到 iOS 6,但我现在想要索引!
有什么解决办法吗?
好吧,有办法做到这一点!将索引方法作为类别添加到 NSArray 和 NSDictionary,您可以获得大多数您想要的类的功能。您可以在此处阅读 ObjectiveC 文字。并且感谢 James Webster 的 @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 );
}
编辑:好吧,根据一位关键的 llvm/clang Apple 工程师的说法,有一个库已经与实现链接,所以你只需要接口文件:
日期:2012 年 8 月 20 日星期一 15:16:43 -0700 发件人:Greg Parker 收件人:... 主题:回复:如何使 Obj-C 集合下标在 iOS 5 上工作?...
作为一个实验,我为这些方法添加了@interface 类别,但没有添加@implementation——应用程序仍然运行良好(至少在 5.1 模拟器中)
编译器发出相同的调用。神奇之处在于名称越来越不准确的 libarclite(“It's Not Just For ARC Anymore™”),如果下标方法尚不存在,它会在运行时添加下标方法的实现。
IIRC 有一些 libarclite 没有升级的可下标的类(NSOrderedSet,也许?)所以你仍然需要在旧的部署目标上进行彻底的测试。