2010-05-12 13 views
10

Ich bin neu in iPhone Entwicklung und ich habe eine Frage, die eine sehr einfache Antwort haben kann. Ich versuche, einer Ansicht Schaltflächen hinzuzufügen, und diese Schaltflächen sind einer benutzerdefinierten Klasse zugeordnet, die ich definiert habe. Wenn ich die Schaltflächen zur Ansicht hinzufüge, würde ich gerne wissen, welcher Klasse diese Schaltflächen entsprechen. Dies ist, weil, wenn ich den Knopf drücke, ich einige Informationen über die Klasse erhalten muss, aber der Empfänger der Nachricht ist eine andere Klasse. Ich konnte keine Informationen über einen Fehler finden, den ich im Internet erhalte. Das Problem, das ich habe ist, dass ich versuche, eine NSMutableDictionary zu schaffen, wo die Schlüssel vom Typ UIButton * sind und die Werte sind mein benutzerdefinierter Typ:NSMutableDictionary mit UIButton * als Schlüssel - iPhone Entwicklung

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

Natürlich ist der sourceButtonMap in der Klasse definiert und initialisiert in der init-Funktion als sourceButtonMap = [[NSMutableDictionary alloc] init];

der Fehler ich erhalte, wenn ich versuche, das Schlüssel-Wert-Paar hinzuzufügen ist:

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

Ist das passiert, weil ich UIButton * nicht als Schlüssel speichern kann? Kann mir jemand zeigen, warum ich diesen Fehler bekomme? Vielen Dank an alle,

aa

Antwort

3

Von Apple docs:

Der Schlüssel kopiert wird (mit copyWithZone :; Schlüssel zu das NSCopying Protokoll entsprechen müssen).

UIButton entspricht nicht das NSCopying Protokoll und so kann man es nicht als Schlüssel verwendet, in NSDictionary

+0

Das ist, was ich dachte, so haben Sie Vorschläge, wie dieses Problem zu lösen? Bei einer UIButton muss ich die benutzerdefinierte Klasse erhalten, die diese Schaltfläche darstellt. Wenn ich kein Wörterbuch benutzen kann, muss es einen anderen Weg geben, dies zu tun. Ich kann ein Array nicht verwenden, da sich mehrere UIButtons auf dasselbe Objekt beziehen können. Gibt es eine Möglichkeit, der Schaltfläche die ID der darstellenden Klasse zu geben? Oder etwas ähnliches? –

16

Einen Weg, ich fand einen NSValue zu verwenden war zu konstruieren als Schlüssel zu verwenden. Um das zu erstellen, verwenden Sie:

[NSValue valueWithNonretainedObject:myButton].

Der Vorbehalt hier scheint, dass, wenn die Schaltfläche Müll gesammelt wird, der Schlüssel eine ungültige Referenz enthalten wird.

Sie können den Verweis auf die UIButton wieder zu bekommen, während wie so durch das Wörterbuch Looping:

for (NSValue* nsv in myDict) { 
    UIButton* b = (UIButton*)[nsv nonretainedObjectValue]; 
    ... 
} 
+0

Ich bin auch mit dem gleichen Problem konfrontiert. Können Sie ausführlich erarbeiten, wie Sie diesen Trick zu implementieren. Ich habe versucht, dies zu tun: - aber die App wird abgestürzt. \t \t NSDictionary * catPassdict = [NSDictionary-Wörterbuch]; \t \t \t \t \t [catPassdict setWert: [NSValue valueWithNonre tainedObject: catAppButton] forKey: @ "btn"]; – Gypsa

2

ich einen kühlen Trick dafür haben.

Ich werfe den Zeiger auf ein int (da das alles ein Zeiger wirklich ist) und speichern Sie es in einer NSNumber. Die Verwendung der NSNumber als Schlüssel löst dieses Problem und macht Sinn sinnvoll, denn wen interessiert es, eine Kopie der Schaltfläche im Wörterbuch zu speichern? Es macht mir mehr Sinn, eine Kopie der Zeigerinformationen zu speichern.

Wenn Sie wie ich, werden Sie wahrscheinlich auch dieses Bit in ein Makro wickeln. Etwas wie folgt aus:

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

Dann ist es ein wenig sauberer in Code zu verwenden ...

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]; 
} 
+1

und ein cooler Trick für Sie: Verwenden Sie das integrierte Markup im Formular anstelle von HTML-Tags. – vikingosegundo

2

UIButtons haben eine description Eigenschaft, die als Wörterbuch Schlüssel verwendet werden können:

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 
+0

Wenn mehr als ein UIButton als Schlüssel im Wörterbuch verwendet wird, gibt es dann eine Garantie, dass jeder einen eindeutigen, unveränderlichen Wert für seinen Beschreibungseigenschaftswert hat? (Ich habe versucht, diesen Ansatz zu verwenden und den Eigenschaftswert für die Beschreibung selbst zu setzen, aber er ist schreibgeschützt.) –

+0

Ich habe diese Lösung mit mehreren UIB-Tasten verwendet und es funktioniert einwandfrei. In meinem Fall ist keine benutzerdefinierte Beschreibung erforderlich. – synthresin