2010-05-12 12 views
10

Soy nuevo en el desarrollo de iPhone y tengo una pregunta que puede tener una respuesta muy simple. Estoy intentando agregar botones a una vista y estos botones están asociados con una clase personalizada que definí. Cuando agregue los botones a la vista, me gustaría saber a qué clase corresponden estos botones. Esto es porque cuando presiono el botón, necesito obtener información sobre la clase, pero el receptor del mensaje es otra clase. No pude encontrar información sobre un error que estoy recibiendo en la web. El problema que tengo es que estoy tratando de crear un NSMutableDictionary dónde están las llaves del tipo UIButton * y los valores son de mi tipo personalizado:NSMutableDictionary con UIButton * como claves - Desarrollo de iPhone

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

Por supuesto, el sourceButtonMap se define en la clase e inicializado en la función de inicio como el sourceButtonMap = [[NSMutableDictionary alloc] init];

el error que consigo cuando intento añadir el par clave-valor es:

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

¿Esto está sucediendo porque no puedo almacenar UIButton * como claves? ¿Alguien me puede indicar por qué me sale este error? Gracias a todos,

aa

Respuesta

3

De Apple docs:

se copia la clave (usando copyWithZone :; teclas deben cumplir con el protocolo NSCopying).

UIButton no se ajusta al protocolo NSCopying y por lo que no se puede utilizar como una clave en NSDictionary

+0

Eso es lo que pensé, así que ¿Tiene alguna sugerencia sobre cómo resolver este problema? Dado un UIButton, necesito obtener la clase personalizada que ese botón representa. Si no puedo usar un diccionario, tiene que haber otra forma de hacerlo. No puedo usar una matriz porque varios UIButtons pueden referirse al mismo objeto. ¿Hay alguna manera de darle al botón la identificación de la clase que representa? ¿O algo similar? –

16

Una forma que encontré fue utilizar construir un NSValue utilizar como clave. Para crear el uso:

[NSValue valueWithNonretainedObject:myButton].

La advertencia aquí parece ser que si el botón es basura recogida, la clave tendrá una referencia no válida.

Usted puede obtener la referencia a la UIButton otra vez mientras recorriendo el Diccionario de este modo:

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

También estoy enfrentando el mismo problema. ¿Puede explicar cómo implementar este truco? Intenté hacer esto: - pero la aplicación se está cayendo. \t \t NSDictionary * catPassdict = [NSDictionary dictionary]; \t \t \t \t \t [catPassdict setValue: [NSValue valueWithNonretainedObject: catAppButton] forKey: @ "btn"]; – Gypsa

2

Tengo un buen truco para esto.

I lanzar el puntero a un int (ya que todo es realmente un puntero) y almacenarlo en un NSNumber. El uso de NSNumber como clave resuelve este problema y tiene sentido desde el punto de vista del fundamento, porque ¿a quién le importa almacenar una copia del botón en el diccionario? Tengo más sentido para mí almacenar una copia de la información del puntero.

Si te gusto, probablemente también incluirás ese bit en una macro. Algo como esto:

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

Entonces es un poco más limpio para su uso en el código ...

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

y un truco genial para ti: utiliza el marcado integrado provisto en el formulario en lugar de etiquetas html. – vikingosegundo

2

UIButtons tienen una propiedad description que puede ser utilizado como una clave de diccionario:

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

Si hay más de un UIButton utilizado como claves en el diccionario, ¿hay alguna garantía de que cada uno tenga un valor único e inmutable para su valor de propiedad de descripción? (Traté de tomar este enfoque y configurar el valor de propiedad de la descripción, pero es de solo lectura.) –

+0

Utilicé esta solución con múltiples UIButton y funciona bien. En mi caso, no se necesita una descripción personalizada. – synthresin

Cuestiones relacionadas