我同意大多数应使用objectForKey: 或类似方法访问NSDictionary 的答案。但是,可以允许点符号访问NSDictionary,并且出于学习目的,这可能对某些人来说很有趣。此外,例如,当您通过 AFNetworking 检索大型 JSON 字典时,此方法可以简化代码的访问和可读性。
这是我的解决方案:
DictionaryProperties.h:(包装 NSDictionary 以进行属性访问的类)
@interface DictionaryProperties : NSObject{
NSMutableDictionary* _backingDict;
}
@property (nonatomic, strong) NSMutableDictionary* backingDict;
+ (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict;
@end
DictionaryProperties.m:
#import "DictionaryProperties.h"
@implementation DictionaryProperties
@synthesize backingDict = _backingDict;
- (id) initWithDictionary:(NSDictionary*)dict {
if (self) {
if ([dict isKindOfClass:[NSMutableDictionary class]]) {
self.backingDict = (id)dict;
} else {
self.backingDict = [[NSMutableDictionary alloc] initWithDictionary:dict];
}
}
return self;
}
+ (DictionaryProperties*) allocWithDictionary:(NSDictionary*)dict {
return [[DictionaryProperties alloc] initWithDictionary:dict];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
NSString* key = NSStringFromSelector(invocation.selector);
invocation.selector = @selector(objectForKey:);
[invocation setArgument:&key atIndex:2];
if ([self.backingDict objectForKey:key]) {
[invocation invokeWithTarget:self.backingDict];
} else {
[self doesNotRecognizeSelector:invocation.selector];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
return [self.backingDict methodSignatureForSelector:@selector(objectForKey:)];
}
@end
ExampleDictContent.h:(声明字典内容的类)
#import "DictionaryProperties.h"
@interface ExampleDictContent : DictionaryProperties
@property (strong, nonatomic) NSString* someData;
@property (strong, nonatomic) NSString* someOtherData;
@end
@implementation ExampleDictContent
@end
用法:(字典的简单声明,包装器的分配和属性访问)
#import "ExampleDictContent.h"
NSDictionary* d = [NSDictionary dictionaryWithObjects:NSArray arrayWithObjects:@"someData content", @"someOtherData content", nil
forKeys:NSArray arrayWithObjects:@"someData", @"someOtherData", nil];
ExampleDictContent* dictWProps = [ExampleDictContent allocWithDictionary:d];
NSLog(dictWProps.someData);
NSLog(dictWProps.someData);
这将打印:
someData content
someOtherData content
所以基本上DictionaryProperties 用作访问NSDictionary 的门面。它使用forwardInvocation 将get-property 方法调用转换为对字典的getObjectForKey: 调用。我喜欢它的地方是它允许在字典上自动完成,并且还允许我明确声明我想要访问的键(在ExampleDictContent.h 文件中)。请注意,此解决方案不允许对属性进行写访问,但可以按照下面的链接添加。
此解决方案部分受到karstenlitsche's solution 的启发。主要区别在于该解决方案基于子分类而不是类别。