4

私は、例外の使用に慣れているPythonの世界の開発者です。私は多くの場所で例外を使用することはそれほど賢明ではないことを発見し、必要に応じてNSErrorsに変換するために最善を尽くしました。しかし、私はこれに遭遇します:

NSMutableArray *results;
for (NSDictionary *dict in dicts)
{
    // Memory management code omitted
    SomeModel *model = [[SomeModel alloc] init];
    model.attr1 = [[dict objectForKey:@"key1"] integerValue];
    model.attr2 = [[dict objectForKey:@"key2"] integerValue];
    model.attr3 = [[dict objectForKey:@"key3"] integerValue];
    model.attr4 = [[dict objectForKey:@"key4"] integerValue];

    [results addObject:model];
}

dict内の一部のオブジェクトにNSNullが含まれているため、「認識されないセレクター」例外が発生します。その場合、そのデータムを完全に削除したいと思います。私の最初の本能は、forブロックのコンテンツ全体を@ try-@catchブロックにラップすることです。

NSMutableArray *results;
for (NSDictionary *dict in dicts)
{
    @try
    {
        SomeModel *model = [[SomeModel alloc] init];
        model.attr1 = [[dict objectForKey:@"key1"] integerValue];
        model.attr2 = [[dict objectForKey:@"key2"] integerValue];
        model.attr3 = [[dict objectForKey:@"key3"] integerValue];
        model.attr4 = [[dict objectForKey:@"key4"] integerValue];

        [results addObject:model];
    }
    @catch(NSException *exception)
    {
        // Do something
    }
}

しかし、これは良いアプローチですか?各変数のチェックを繰り返さずに解決策を思いつくことはできません。これは本当に醜いIMOです。うまくいけば、私には思いつかなかったこれに代わるものがあります。前もって感謝します。

4

3 に答える 3

3

これを行うための適切なObjective-Cの方法は次のとおりです。

for (NSDictionary *dict in dicts)
{
    if (! [dict isKindOfClass:[NSDictionary class]])
        continue;
    // ...
}

受信者がメッセージを送信する前にメッセージに応答できるかどうかをテストすることは、Objective-Cの典型的なパターンです。

また、Objective-Cの例外は常にプログラマーエラーであり、通常の実行フローには使用されないことに注意してください。

于 2012-10-31T10:18:56.550 に答える
1

多くの人がこれらの場合にNSDictionaryのカテゴリを使用します。

- (id)safeObjectForKey:(id)aKey
{
  id obj = [self objectForKey:aKey];
  if ([obj isKindOfClass:[NSNull class]])
  {
    return nil;
  }

  return obj;
}

dictが実際の辞書インスタンスであることを確認する必要があります。

于 2012-10-31T11:03:12.197 に答える
0

結局、私はKVCを使用して問題を解決することにしました。このようなもの:

- (id)initWithPropertyDictionary:(NSDictionary *)dict
                     lookUpTable:(NSDictionary *)keyToProperty
{
    self = [self init];
    for (NSString *key in dict)
    {
        NSString *propertyName;
        if ([keyToProperty objectForKey:key])
            propertyName = [keyToProperty objectForKey:key];
        else
            propertyName = key;
        if ([[dict objectForKey:key] isKindOfClass:[NSNull class]])
        {
            [self release];
            return nil;
        }
        else
        {
            [self setValue:[dict objectForKey:key] forKey:propertyName];
        }
    }
}

この解決策の欠点は、プロパティにNSNumberを使用する必要があることですが、JSONデータの場合、浮動小数点数と整数の区別が実際にはないため、これで問題ありません。

また、プリミティブ型が本当に必要な場合は、このメソッドを、それらのNSNumberを適切な型に変換するカスタムセッターと組み合わせることができます。

これにより、オブジェクトを配列に追加する前に、nilをチェックするだけで済みます。モデルクラスを除いてどこでもはるかにきれい。

モデルクラスの変更に集中するように促してくれたjaydee3に感謝します。

于 2012-11-02T06:52:15.380 に答える