[英]Key-Value Coding Get Element in List
我有两个对象:
@interface AObject : NSObject
@property NSArray *bObjects;
@end
@interface BObject : NSObject
@property NSString *name;
@end
在AObject
的实例上使用键值编码,我可以获得bObjects
的列表( @"self.bObjects"
)和bObjects
名称的列表( @"self.bObjects.name"
)。
但是,我想要的只是第一个bObjects
的名称。 我的直觉是键值编码应支持列表下标,例如: @"bObjects[0].name"
。
但这似乎并不存在。 我如何获得一个实体? 使用键值编码的AObject
的第一个BObject
的名称?
脚注:我意识到在最后一个问题中,我愚蠢地将NSPredicate和KV编码混为一谈。
正如Martin R在评论中提到的那样,当前最好的选择是在AObject
类中创建firstBObject
属性。
AObject.h /米
@class BObject;
@interface AObject : NSObject
+ (AObject*)aObjectWithBObjects:(NSArray*)bObjects;
@property NSArray *bObjects;
@property (nonatomic, readonly) BObject *firstBObject;
@end
@implementation AObject
+ (AObject*)aObjectWithBObjects:(NSArray*)bObjects
{
AObject *ao = [[self alloc] init];
ao.bObjects = bObjects;
return ao;
}
- (BObject*)firstBObject
{
return [self.bObjects count] > 0 ? [self.bObjects objectAtIndex:0] : nil;
}
@end
BObject.h /米
@interface BObject : NSObject
+ (BObject*)bObjectWithName:(NSString*)name;
@property NSString *name;
@end
@implementation BObject
+ (BObject*)bObjectWithName:(NSString *)name
{
BObject *bo = [[self alloc] init];
bo.name = name;
return bo;
}
@end
用法:
NSArray *aobjects = @[
[AObject aObjectWithBObjects:@[
[BObject bObjectWithName:@"A1B1"],
[BObject bObjectWithName:@"A1B2"],
[BObject bObjectWithName:@"A1B3"],
[BObject bObjectWithName:@"A1B4"]
]],
[AObject aObjectWithBObjects:@[
[BObject bObjectWithName:@"A2B1"],
[BObject bObjectWithName:@"A2B2"],
[BObject bObjectWithName:@"A2B3"],
[BObject bObjectWithName:@"A2B4"]
]],
[AObject aObjectWithBObjects:@[
[BObject bObjectWithName:@"A3B1"],
[BObject bObjectWithName:@"A3B2"],
[BObject bObjectWithName:@"A3B3"],
[BObject bObjectWithName:@"A3B4"]
]]
];
NSLog(@"%@", [aobjects valueForKeyPath:@"firstBObject.name"]);
结果
(
A1B1,
A2B1,
A3B1
)
事实证明,我很幸运能够简单地在根类( AObject
)中重写-valueForKey:
AObject
值得重申的是-valueForKeyPath:
呼吁-valueForKey:
在每一个关键,这是很酷。
由于这可能并不适用于所有人,并且可能过多地操纵了默认的预期行为,所以这绝对不是 “正确”的答案。
但是无论如何,这里是:
- (id)valueForKey:(NSString *)string
{
if ([string characterAtIndex: [string length] - 1] == ']') // Trying to subscript
{
NSRegularExpression *subscriptRegex = [[NSRegularExpression alloc] initWithPattern: @"([a-zA-Z]+)\\[([0-9]+)\\]"
options: (NSRegularExpressionOptions)0
error: nil];
NSString *key = [subscriptRegex stringByReplacingMatchesInString: string
options: (NSMatchingOptions)0
range: NSMakeRange(0, [string length])
withTemplate: @"$1"];
id valueForKey = [self valueForKey: key];
if (!key || !valueForKey || ![valueForKey respondsToSelector: @selector(objectAtIndexedSubscript:)])
return nil;
NSInteger index = [[subscriptRegex stringByReplacingMatchesInString: string
options: (NSMatchingOptions)0
range: NSMakeRange(0, [string length])
withTemplate: @"$2"] integerValue];
if ((index < 0) || (index >= [valueForKey count]))
return nil;
return [valueForKey objectAtIndexedSubscript: index];
}
return [super valueForKey: string];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.