22

NSArrayで要素にアクセスする方法はありますvalueForKeyPathか? たとえば、Google のリバース ジオコーダー サービスは、非常に複雑なデータ構造を返します。都市を取得したい場合は、次のように 2 つの呼び出しに分割する必要があります。

NSDictionary *address = [NSString stringWithString:[[[dictionary objectForKey:@"Placemark"] objectAtIndex:0] objectForKey:@"address"]];
NSLog(@"%@", [address valueForKeyPath:@"AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName"]);

objectAtIndex:呼び出しを文字列にシューホーンする方法があるかどうか疑問に思っていvalueForKeyPathます。@"Placemark[0].address" のような JavaScript 風の定式化を試みましたが、ダイスはありませんでした。

4

5 に答える 5

19

これは、配列インデックスを処理できる 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"];

エラーチェックがないため、壊れやすいですが、アイデアは得られます。

于 2012-12-07T03:49:24.050 に答える
19

残念だけど違う。Key-Value Coding を使用して何が許可されるかについての完全なドキュメントは、こちらです。私の知る限り、特定の配列またはセット オブジェクトを取得できる演算子はありません。

于 2009-09-22T16:58:31.917 に答える
3

NSArray を保持するオブジェクトでキーパスをインターセプトできます。

あなたの場合、キーパスは Placemark0.address... になります。 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などのモデル フレームワークで非常にうまく機能します。

于 2013-09-30T19:16:47.897 に答える