1

Objective-C では、多くの Mutable オブジェクトを作成し、それらを非可変オブジェクトとして返すことに気付きました。私がここでやっている方法は、単に良い習慣NSMutableSetとして返すだけですか? NSSetコピーを作成するように指定する必要があるのではないかと考えていました。

/**  Returns all the names of the variables used in a given
 *   program. If non are used it returns nil */
+ (NSSet *)variablesUsedInProgram:(id)program
{
    NSMutableSet* variablesUsed = [[NSMutableSet alloc]init];
    if ([program isKindOfClass:[NSArray class]]) {
        for (NSString *str in program)
        {
            if ([str isEqual:@"x"] || [str isEqual:@"y"] || [str isEqual:@"a"] || [str isEqual:@"b"])
                [variablesUsed addObject:str];
        }
    }
    if ([variablesUsed count] > 0) {
        return variablesUsed;
    } else {
        return nil;
    }
}
4

4 に答える 4

2

どの程度の安全性が必要かによって異なります。オブジェクトを NSSet として返す場合、それは NSMutableSet のままであるため、簡単に NSMutableSet にキャストして変更することができます。

確かに、パブリック API を作成している場合は、コピーを返すことをお勧めします。内部プロジェクトの場合、おそらくメソッド シグネチャはすでに意図を十分に明確にしています。

注目に値するのは、通常、コピーを返すことによるパフォーマンスへの影響はごくわずかです。不変インスタンスのコピーは事実上無料ですが、mutable-passing-as-immutable に送信された各コピーは別のコピーを作成します。したがって、デフォルトにすることをお勧めします。

于 2013-01-29T22:42:05.980 に答える
2

私があなたなら、このようにします。

+ (NSSet *)variablesUsedInProgram:(id)program
{
    NSSet *variablesUsed;
    if ([program isKindOfClass:[NSArray class]]) {
      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 'x' or SELF = 'y' or SELF = 'z'"];
      variablesUsed = [NSSet setWithArray:[program filteredArrayUsingPredicate:predicate]];  
    }
    int count;
    return (count = [variablesUsed count]) > 0 ? variablesUsed : nil;
}

述語を使用して配列をフィルタリングすることは、非常に包括的で簡単です。新しい変更可能な型を作成してから特定の条件をテストするのではなく、until ループを追加します。このシナリオでは、述語を使用する方が簡単なようです。これがお役に立てば幸いです。

于 2013-01-30T00:30:43.713 に答える
0

いいえ。これは絶対的に正しいOOPアプローチです(ポリモーフィズムを利用します)。すべてNSMutableSetが適切NSSetです。過度にコピーしないでください。

于 2013-01-29T22:36:20.750 に答える
0

ここでは完全な答えではありません.NSProxyの答えを考えてください.しかし、私は何かを明確にしたい.

あなたの場合、オブジェクトを最初から作成し、そのオブジェクトを指す ivar を設定しません。私の意見では、かなりの割合のケースで、返された可変オブジェクトのコピーを作成する必要はありません。しかし、クラス クライアントがクラスを変更することを拒否する十分な理由がある場合は、変数をコピーする必要があります。

次のようなプロパティを検討してください。

@property (nonatomic,assign) NSSet* set;

クラスクライアントはこれを行うことができます:

NSMutableSet* set= ... ; // inizialized to some value
classInstance.set= set;
// Mutate the set

セットを変更すると、クラスが一貫性のない状態になる可能性があります。

そのため、変更可能なバージョンも持つクラスの型を持つプロパティがある場合、常にそのプロパティに割り当てではなくコピーを配置します。

于 2013-01-30T11:28:28.693 に答える