10

私は iPhone の開発に不慣れで、非常に簡単な答えが得られるかもしれない質問があります。ビューにボタンを追加しようとしていますが、これらのボタンは定義したカスタム クラスに関連付けられています。ビューにボタンを追加するとき、これらのボタンが対応するクラスを知りたいです。これは、ボタンを押すときにクラスに関する情報を取得する必要があるためですが、メッセージの受信者は別のクラスです。Web 上で発生しているエラーに関する情報を見つけることができませんでした。私が抱えている問題は、キーが UIButton* 型で値がカスタム型である NSMutableDictionary を作成しようとしていることです:

   // create button for unit
   UIButton* unitButton = [[UIButton alloc] init];
   [sourceButtonMap setObject:composite forKey:unitButton];

もちろん、sourceButtonMap はクラスで定義され、init 関数で次のように初期化されます。sourceButtonMap = [[NSMutableDictionary alloc] init];

キーと値のペアを追加しようとすると、次のエラーが表示されます。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIButton copyWithZone:]: unrecognized selector sent to instance 0x3931e90'

UIButton* をキーとして保存できないため、これが発生していますか? このエラーが発生する理由を教えてもらえますか? 皆さん、ありがとうございました、

ああ

4

4 に答える 4

16

私が見つけた1つの方法は、キーとして使用するNSValueの構築を使用することでした。その使用を作成するには:

[NSValue valueWithNonretainedObject:myButton]

ここでの注意点は、ボタンがガベージコレクションされている場合、キーが無効な参照を保持することです。

次のようにディクショナリをループしながら、UIButtonへの参照を再度取得できます。

for (NSValue* nsv in myDict) {
    UIButton* b = (UIButton*)[nsv nonretainedObjectValue];
    ...
}
于 2010-07-07T18:28:48.167 に答える
3

アップルのドキュメントから:

キーがコピーされます (copyWithZone: を使用して、キーは NSCopying プロトコルに準拠する必要があります)。

UIButton は NSCopying プロトコルに準拠していないため、NSDictionary でキーとして使用することはできません

于 2010-05-12T15:44:12.187 に答える
2

これにはクールなトリックがあります。

ポインターを int にキャストし (ポインターはこれだけなので)、NSNumber に格納します。NSNumber をキーとして使用すると、この問題が解決され、根本的に理にかなっています。ポインターの情報のコピーを保存する方が理にかなっています。

あなたが私のような人なら、おそらくそのビットもマクロにラップするでしょう。このようなもの:

#define BOX_AS_NUM(_ptr_) [NSNumber numberWithInt:(int)_ptr_]

次に、コードで使用するのが少しきれいです...

NSDictionary* btnMap = [NSDictionary dictionaryWithObjectsAndKeys:some_obj, BOX_AS_NUM(some_btn), nil];
-(IBAction)someBtnAction:(id)sender
{
    SomeObj* obj = [btnMap objectForKey:BOX_AS_NUM(sender)];
    [obj doCoolStuffBecuaseIWasJustClicked];
}
于 2011-05-15T04:29:29.627 に答える
2

UIButton にはdescription、辞書キーとして使用できるプロパティがあります。

NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] initWithCapacity:1];
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 10.0f, 10.0f)];
id myObject;
[myDictionary setObject:myObject forKey:myButton.description];

// somewhere else in code
id myLookedUpObject = [myDictionary objectForKey:myButton.description];
// do something with myLookedUpObject
于 2011-12-07T16:58:19.517 に答える