OC对象下标索引和键索引

对于NSArrayNSDictionary我们可以通过下标直接访问对象,比如

1
2
3
4
NSArray *arr = @[@"a", @"b", @"c"];
arr[1]; // b
NSDictionary *dic = @{@"k1": @"v1", @"k2": @"v2", @"k3": @"v3"}
dic[@"k1"]; // v1

其实对于普通NSObject类,我们通过实现一些方法也可以实现类似功能

1
2
3
4
5
6
7
//实现类似数组下标索引只需实现以下方法
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;

//实现类似字典键索引只需实现以下方法
- (id)objectForKeyedSubscript:(id)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;

具体使用举个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/// MHKeyedSubscript.h
@interface MHKeyedSubscript : NSObject
/// 类方法
+ (instancetype) subscript;

- (id)objectForKeyedSubscript:(id)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;

- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
@end

@interface MHKeyedSubscript ()
/// 字典
@property (nonatomic, readwrite, strong) NSMutableDictionary *kvs;
@end

/// MHKeyedSubscript.m
@implementation MHKeyedSubscript

+ (instancetype) subscript {
return [[self alloc] init];
}

- (instancetype)init
{
self = [super init];
if (self) {
self.kvs = [NSMutableDictionary dictionary];
}
return self;
}

- (id)objectForKeyedSubscript:(id)key {
return key ? [self.kvs objectForKey:key] : nil;
}

- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key {

if (key) {
if (obj) {
[self.kvs setObject:obj forKey:key];
} else {
[self.kvs removeObjectForKey:key];
}
}
}

- (id)objectAtIndexedSubscript:(NSUInteger)idx {
return @(idx);
}

- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx {
NSLog(@"set %tu = %@", idx, obj);
}

@end
1
2
3
4
5
6
7
/// ViewController.m
MHKeyedSubscript *subscript = [MHKeyedSubscript subscript];
subscript[0] = @"hkkb"; // set 0 = hkkb
NSLog(@"%@", subscript[0]); // 0

subscript[@"k1"] = @"v1";
NSLog(@"k1: %@", subscript[@"k1"]); // k1: v1