1

何時間も調べたり遊んだりしてきた奇妙な質問があります。

私はNSMutableDictionary、キーをタイトルとして、値をメモとしてメモを保存する、単純なメモ作成アプリに取り組んでいます。NSTextViewの内容が変更されるたびに保存するデリゲート関数があります。

-(void)textDidChange:(NSNotification *)notification {
    NSString *currentNote = [_mainTextField string];
    [Data setNote:currentNote forKey:currentKey];
}

次に、辞書に追加します。

+(void)setNote:(NSString *)note forKey:(NSString *)key {
    [allNotes setObject:note forKey:key];
}

whilecurrentKeyは、他の場所で更新されるグローバル変数です (そして、私は徹底的にテストし、正常に動作しています)。

ここが奇妙になりsetNote:forKey:ます。キーがすべて一意である限り、辞書は の呼び出しごとに 1 つのキーを更新することを期待するでしょう。しかし、代わりに、以前に更新されたすべてのキーを毎回更新しています。 したがって、このような辞書があれば。

"John" = "apples";
"David" = "apples";

「ジョン」を「バナナ」に更新しました

"John" = "bananas";
"David" = "apples";

「David」を「oranges」に更新すると、次のようになります。

"John" = "oranges";
"David" = "oranges";

私はブレークポイントを作成し、NSLog を作成しました。私が発見したのは、行が呼び出される前にsetNote:forKey:、メソッドの開始までに「John」が「oranges」に変更されることです。 さて、これは私のプログラム全体で辞書を変更する唯一の場所ですが、どういうわけか、関数が呼び出される前に元の行が再変更されています。最初の変更 (「バナナ」ラウンド) では、ディクショナリのサイズや変更対象のエントリに関係なく、すべてが完全に機能し、2 回目 (「オレンジ」ラウンド) を除いて、すべてが再び完全に機能します。以前に変更された行も変更します。[allNotes setObject:note forKey:key]allNotes

textDidChange:キーが押された正確な瞬間に呼び出され、その時点までに最初のエントリが既に変更されているため、コードの原因をこれ以上正確にする方法がわかりません。特に、アプリを停止して再実行すると、最初の変更が正常に行われ、すべてが再び開始されます。

もう 1 つの奇妙な点は、キー変数が正常に機能していることです。デバッガーでチェックインしました。グローバル変数currentKeyとそれから派生したローカル変数の両方keyが「David」になりますが、変更は「David」と「John」の両方に影響し、「John」の前に変更された他の変数にも影響します. 現在の Key 値だけを使用して、以前に編集された行をどのように知ることができるでしょうか?

私は確かにココアの初心者ですが、完全に困惑しています。誰かが私のためにこれに光を当てることができますか?

4

1 に答える 1

1

キーと値のペアがディクショナリに追加されると、キーはコピーされますが、値は保持されます。キーはコピーされるため、変更できません。ディクショナリの内部編成はキーに基づいています。

値はディクショナリ内に存在し続ける必要があるため保持されますが、値が変更可能な型である場合は、変更しても問題ありません。たとえば、オブジェクトの辞書を作成するNSTextFieldと、キーとNSTextFieldオブジェクトの関連付けは固定されますが、個々のテキスト フィールド自体の内容は変更される可能性があります。

あなたのコードでは、呼び出されるたびに同じ[_mainTextField string]オブジェクトへの参照が返されているようです。これは、ディクショナリ内のすべての値が同じ可変オブジェクトへの参照であり、見ている動作を提供することを意味します。内部で使用している変更可能な文字列をコピーして を返すように変更することで、これに対処できます。または、 を使用して返されたものをコピーします。の目的が の現在の値のスナップショットを返すことである場合は、前者の方が適しています(その型が何であれ、サンプルには記載されていません)。 NSMutableString[_mainTextField string]NSString[[_mainTextField string] copy][_mainTextField string]_mainTextField

于 2013-06-14T16:13:39.193 に答える