2010-12-05 5 views
2

半複雑なビューアニメーションを作成しようとしています(他の行が追加または削除されたときに行がスライドするNSMatrixフォームのアニメーションバージョンを考えてください)ヘルパークラス。NSDictionaryキーとしてNSViewインスタンスを使用していますか?

私は、さまざまなビュー、順序付けられたインデックス、およびアニメーションに関連付けられたいくつかの他の値を追跡する必要があります。

この目的のために、ビューの順序(インデックス)を把握するためにNSArrayインスタンスを使用しています。このビューをキーとして使用して、ビューをキーとして保持したいと考えています値そのものはネストされた辞書にあります)。私。私は、例えば、(擬似コード)何かこれを行うことができるようにしたい:

NSMutableDictionary* viewValuesDict = [NSDictionary dictionary]; 

// Loop thru an ordered NSArray 
for((NSView*) view in viewsArray) { 
    // Get some values we'll need later 
    NSDictionary* associatedValues = [view getSomeValues]; 

    // ...and put them into viewValuesDict... 
    [viewValuesDict setObject:associatedValues forKey:view]; 

    // and then things break because the NSView 'view' 
    // doesn't support copyWithZone.... darn 
} 

問題は、私は、あるキーは使用して追加されているので、辞書のキーとしてNSViewのインスタンスを使用することはできませんもちろん、 copyWithZoneNSViewは実装されていません。

NSViewインスタンスのユニークなキーを取得するにはどうすればよいですか? [obj description]を使用することができます。なぜなら、戻ってくるメモリアドレスは完璧なUIDだからです。もちろん、システムは何か別のものを返す可能性がある任意の種類のNSViewサブクラスで動作する必要があります。

他にも何かを試してみるべきですか?キーがちょうどコピーされないNSDictionaryの代替案がありますか?この場合、私は本当にキーをコピーする必要はありません。

答えて

8

時には、ビュー(NSまたはUIのいずれか)を辞書のキーとして使用する場合があります。私はそのような状況に遭遇しました。私はobjc_setAssociatedObjectを使用することを好みましたが、それにはSnow Leopardが必要です。 NSValueでボクシングは動作しますが、ビューを与えられたルックアップの多くと多くを行う必要がある場合は、継続的なボクシングとポインタのunboxingは退屈になるかもしれません。

NSView => <object>辞書を作成するには、2つの方法があります。

  1. 使用NSMapTable
  2. 使用CFMutableDictionaryRef

NSMapTableそれがガベージコレクションでもっとうまく動作させる余分な能力を持っていることを除いて、NSMutableDictionaryに非常に似て10.5で導入されたクラスです。あなたの場合は、おそらく "弱い"キーと "強い"値を持つマップテーブルが必要ですが、すべての楽しい詳細のドキュメントをお読みください。

CFMutableDictionaryRefは、NSDictionary(これはフリーダイヤルです)のコアファウンデーションに相当しますが、追加の作成オプションがあります。 CFDictionaryCreateMutable()を使用して作成し、2つのstructパラメータが必要です。 1つは、辞書のキーを扱う方法のメモリ管理(およびその他の)動作を定義する構造体であり、もう1つは値の動作を定義するためのstructです。 CFMutableDictionaryRefを作成するには、(コピーする代わりに)キーを保持し、値を保持するオプションがあります。これをやり終えたら、CFMutableDictionaryRefNSMutableDictionaryにキャストして、期待どおりに使用してください。コピーされずにキーが保持されるだけです。

+0

Veeeery面白い!私は間違いなくそれらを試してみる必要があります。私が別のコメントで言うように、私はSnow Leopardをターゲットにしていますが、私は非常に長い間ぶつかる必要はないので、 'objc_setAssociatedObject'はおそらく過剰です。 NSMapTableとCFMutableDictionaryRefは両方とも、しかし彼らが完全に法案に適合するかもしれないように聞こえる。ありがとう! – Flambino

0

辞書の値の1つがビューになるように辞書を作成します。ビューに基づいて辞書を検索する必要はなく、辞書やインデックス(辞書を配列に入れる)、または独自の作成の一意のIDで始めるようにコードを並べ替えることができます(ディクショナリをこのIDは、あなたが追跡し始めた新しいビューごとに連続した番号と同じくらいシンプルにすることができます)。非常に複雑で動的なことをしない限り、NSViewの情報だけを検索する必要はありません。

+0

ありがとうございました。ええ、私もそれについて考えていました。私はちょうどolとしてオブジェクトをキーとして使用するいくつかの方法があったと思った。 (少なくとも私には)オブジェクトをキーとして使うことは、オブジェクト上にいくつかの追加のプロパティを「偽装する」簡単な方法であると思われます。 – Flambino

+0

いいえ。キーには本当に固有のプロパティがあります。それは辞書を効果的にするものです。 NSViewに追加のプロパティを追加しようとしているのであれば、なぜサブクラス化していないのですか?それはまさにサブクラスのためのものです! – andyvn22

+0

コードは、特定のサブクラスだけでなく、それを投げたビューでも機能する必要があるためです。さらに、NSViewを簡単に作成できるだけの長さで、いくつかの関連する値を保存しているだけですから、NSViewをいくつか作成してラップすることができますが、残念です。とにかく、NSMapTableはすごくうまく動いています:-) – Flambino

1

andyvn22が言ったように、再編成!しかし、それは実用的ではない場合:

  • あなたはSnow Leopardのをターゲットにしている、と協会は、ビューの生涯持続する可能性がある、objc_setAssociatedObject()を使用している場合。
  • その他の場合は[NSValue valueWithNonretainedObject:]-descriptionよりも優先して使用してください。 (それが言うように、それはオブジェクトを保持しませんが、あなたの配列はありません。)
+0

再編成ができましたが、私はショートカットを望んでいました:-)私はSnow Leopardをターゲットにしていますが、私は非常に短時間の間しか値を必要としないので、 'objc_setAssociatedObject()'をスキップします。しかし、 'valueWithNonretainedObject:'は行く方法かもしれません。私はそれを試してみる - ありがとう! – Flambino

2

利用NSMapTable代わりのNSDictionary(もちろん、あなたが確認する必要がありますが、あなたがしている場合は、慎重にあなたのオブジェクトの寿命を管理するために、ガベージコレクションを使用しない)。 This articleには、その使用方法の概要がよく記載されています。

+0

リンクありがとう! – Flambino

関連する問題