Ответ 1
К сожалению, нет. Полная документация на то, что позволяет использовать кодирование с ключом, здесь. По-моему, не существует никаких операторов, которые позволят вам захватить определенный массив или заданный объект.
Есть ли способ получить доступ к элементу NSArray
с помощью valueForKeyPath
? Служба обратного геокодирования Google, например, возвращает очень сложную структуру данных. Если я хочу получить город, прямо сейчас я должен разбить его на два вызова, например:
NSDictionary *address = [NSString stringWithString:[[[dictionary objectForKey:@"Placemark"] objectAtIndex:0] objectForKey:@"address"]];
NSLog(@"%@", [address valueForKeyPath:@"AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName"]);
Просто интересно, есть ли способ перекодировать вызов objectAtIndex:
в строку valueForKeyPath
. Я пробовал формулировку javascript-esque, например @ "Placemark [0].address", но не кубик.
К сожалению, нет. Полная документация на то, что позволяет использовать кодирование с ключом, здесь. По-моему, не существует никаких операторов, которые позволят вам захватить определенный массив или заданный объект.
Здесь категория, которую я только что написал для NSObject, которая может обрабатывать индексы массивов, чтобы вы могли получить доступ к вложенному объекту, подобному этому: "person.friends [0].name"
@interface NSObject (ValueForKeyPathWithIndexes)
-(id)valueForKeyPathWithIndexes:(NSString*)fullPath;
@end
#import "NSObject+ValueForKeyPathWithIndexes.h"
@implementation NSObject (ValueForKeyPathWithIndexes)
-(id)valueForKeyPathWithIndexes:(NSString*)fullPath
{
NSRange testrange = [fullPath rangeOfString:@"["];
if (testrange.location == NSNotFound)
return [self valueForKeyPath:fullPath];
NSArray* parts = [fullPath componentsSeparatedByString:@"."];
id currentObj = self;
for (NSString* part in parts)
{
NSRange range1 = [part rangeOfString:@"["];
if (range1.location == NSNotFound)
{
currentObj = [currentObj valueForKey:part];
}
else
{
NSString* arrayKey = [part substringToIndex:range1.location];
int index = [[[part substringToIndex:part.length-1] substringFromIndex:range1.location+1] intValue];
currentObj = [[currentObj valueForKey:arrayKey] objectAtIndex:index];
}
}
return currentObj;
}
@end
Используйте его так
NSString* personsFriendsName = [obj valueForKeyPathsWithIndexes:@"me.friends[0].name"];
Нет проверки ошибок, поэтому она подвержена взлому, но вы получаете идею.
Вы можете перехватить путь ключа в объекте, содержащем NSArray.
В вашем случае ключ-путь станет Placemark0.address... Override valueForUndefinedKey; искать индекс в ключевом пути; что-то вроде этого:
-(id)valueForUndefinedKey:(NSString *)key
{
// Handle paths like Placemark0, Placemark1, ...
if ([key hasPrefix:@"Placemark"])
{
// Caller wants to access the Placemark array.
// Find the array index they're after.
NSString *indexString = [key stringByReplacingOccurrencesOfString:@"Placemark" withString:@""];
NSInteger index = [indexString integerValue];
// Return array element.
if (index < self.placemarks.count)
return self.placemarks[index];
}
return [super valueForUndefinedKey:key];
}
Это действительно хорошо работает для модельных рамок, например. Mantle.