[英]Key-Value Coding Get Element in List
I have two objects: 我有两个对象:
@interface AObject : NSObject
@property NSArray *bObjects;
@end
@interface BObject : NSObject
@property NSString *name;
@end
Using key-value coding on an instance of AObject
, I can get the list of bObjects
( @"self.bObjects"
), and a list of bObjects
' names ( @"self.bObjects.name"
). 在
AObject
的实例上使用键值编码,我可以获得bObjects
的列表( @"self.bObjects"
)和bObjects
名称的列表( @"self.bObjects.name"
)。
However, what I want is the name of only the first of bObjects
. 但是,我想要的只是第一个
bObjects
的名称。 My gut is that key-value coding should support list subscripting, like this: @"bObjects[0].name"
. 我的直觉是键值编码应支持列表下标,例如:
@"bObjects[0].name"
。
But that doesn't seem to exist. 但这似乎并不存在。 How do I get a single entity;
我如何获得一个实体? the name of an
AObject
's first BObject
, using key-value coding? 使用键值编码的
AObject
的第一个BObject
的名称?
Footnote: I realized in my last question I was stupidly conflating NSPredicate and KV-coding. 脚注:我意识到在最后一个问题中,我愚蠢地将NSPredicate和KV编码混为一谈。
As Martin R mentioned in the comments, currently the best option would be to create a firstBObject
property in the AObject
class. 正如Martin R在评论中提到的那样,当前最好的选择是在
AObject
类中创建firstBObject
属性。
AObject.h/m 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/m 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
Usage: 用法:
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"]);
Results 结果
(
(
A1B1,A1B1,
A2B1,A2B1,
A3B1A3B1
))
So as it turns out, I had the fortune of being able to simply override -valueForKey:
in the root class ( AObject
). 事实证明,我很幸运能够简单地在根类(
AObject
)中重写-valueForKey:
AObject
It bears repeating that -valueForKeyPath:
calls -valueForKey:
on every key, which is cool. 值得重申的是
-valueForKeyPath:
呼吁-valueForKey:
在每一个关键,这是很酷。
Since that might not be applicable to everyone, and this might be too much manipulation of default, expected behavior, this definitely not the "right" answer. 由于这可能并不适用于所有人,并且可能过多地操纵了默认的预期行为,所以这绝对不是 “正确”的答案。
But here it is anyway: 但是无论如何,这里是:
- (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.