2

NSMutableOrderedSetを使用すると、予期しない動作が発生します。

オブジェクトをインデックス0に設定しました。次の呼び出しで、オブジェクトをインデックス0に読み取りました。返されるポインタが、挿入したばかりのポインタと同じではないのはどうしてですか。

- (void)setRecentObject:(SomeObject *)recentObject
{
    // self.activeQueue is a viable instance of NSMutableOrderedSet

    [[self activeTileQueue] insertObject:recentObject atIndex:0];
    SomeObject *whatIJustInserted = [[self activeTileQueue] objectAtIndex:0];

    DebugLog(@"set url at zero: %@, and read back url at zero: %@",[recentObject someDescription], [whatIJustInserted someDescription]);

}

私の考えでは、このメソッドの最後で、recentObjectは== whatIJustInseretedである必要がありますが、ロギングステートメントとブレークポイントの設定後にポインターを評価する場合の両方で、オブジェクトはSomeObjectの異なるインスタンスです。NSMutableOrderedSetについて理解できないことがありますか?

4

1 に答える 1

8

これが期待どおりに動作しなかった理由は、レシーバーのactiveTileQueue(NSMutableOrderedSetインスタンス)にすでにメンバーが含まれているためです。

オブジェクトの複製を挿入したくないので、特にセットと配列の使用を求めましたが、この場合の挿入がどのように機能するかについての私の仮定は正しくありませんでした。セットに挿入しようとしたメンバーがすでに含まれている場合、再挿入されるのではなく、メンバーは-insertObjectAtIndexで渡されたインデックスに再配置されると想定しました。これは正しくありませんでした。

レシーバーにすでにメンバーが含まれている場合、そのメンバーは再挿入または再注文されません。つまり、何も起こりません。元々望ましい動作を得るには、元のメンバーを削除して再挿入するか、NSMutableOrderedセットで別のメソッドを使用して、セット内のインデックスを再配置/交換する必要があります。例:

NSIndexSet *replacementSet = [NSIndexSet indexSetWithIndex:[[self activeTileQueue] indexOfObject:recentObject]];
[[self activeTileQueue] moveObjectsAtIndexes:replacementSet toIndex:0];
于 2012-12-14T00:44:11.333 に答える