いくつかのマルチタッチ「画面上での描画」コードのメンテナンスで、touchesBegan:withEvent:、touchesMoved:withEvent:、および touchesEnded:withEvent: の間で touches インスタンスへの参照を設定する方法に関するバグに遭遇しました。
このコードは、次のように NSDictionary インスタンスを使用して touchesBegan:withEvent: にタッチの参照を格納します。
for (UITouch *touch in touches]) {
NSValue *touchValue = [NSValue valueWithPointer:touch];
NSString *key = [NSString stringWithFormat:@"%@", touchValue];
[myTouches setValue:squiggle forKey:key];
}
touchesEnded:withEvent: でそれらを取得するには、次のようにします。
for (UITouch *touch in touches) {
NSValue *touchValue = [NSValue valueWithPointer:touch];
NSString *key = [NSString stringWithFormat:@"%@", touchValue];
NSObject *valueFromDictionary = [myTouches valueForKey:key];
[myTouches removeObjectForKey:key];
}
このコードの最後のビットでは、キーがディクショナリに認識されていないため、valueFromDictionary がたまたま nil になることがあります。時折、私は時間の約 1% を意味します。
これでコンテキストが設定されました。私の質問は次のとおりです。
このコードにバグがある理由は何ですか? 特にエラーの頻度が非常に低いため、なぜ機能しないのかわかりません
Apple の一部のドキュメントでは、UITouch オブジェクトのアドレスをキーとして使用することをお勧めします
。ただし、これは、NSString* オブジェクトではなく NSValue* オブジェクトを使用することを意味します (したがって、UITouch はコピーを実装していないため、NSDictionary ではなくCFDictionaryRef を使用することを意味します)。プロトコル)。NSValue 自体ではなく、アドレスの NSString 表現を格納することが、NSDictionary を使用できるようにするための簡単な解決策ではないのはなぜですか?更新: Apple はページを更新し、NSString を介して UITouch を格納する例を削除し、not-object-at-all CFDictionaryRef ソリューションについて言及しています。
残念ながら、私は C やポインターに詳しくないので、このコードにバグがある理由を理解する助けが必要です。