2010-05-12 13 views
10

Sono nuovo nello sviluppo di iPhone e ho una domanda che potrebbe avere una risposta molto semplice. Sto cercando di aggiungere pulsanti a una vista e questi pulsanti sono associati a una classe personalizzata che ho definito. Quando aggiungo i pulsanti alla vista, vorrei sapere a quale classe corrispondono questi pulsanti. Questo perché quando premo il pulsante, ho bisogno di ottenere alcune informazioni sulla classe, ma il destinatario del messaggio è un'altra classe. Non sono riuscito a trovare informazioni su un errore che sto ottenendo sul web. Il problema che ho è che sto cercando di creare un NSMutableDictionary dove le chiavi sono di tipo UIButton * ed i valori sono del mio tipo personalizzato:NSMutableDictionary con UIButton * come chiavi - Sviluppo iPhone

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

Naturalmente, il sourceButtonMap è definito nella classe e inizializzato nella funzione init come sourceButtonMap = [[NSMutableDictionary alloc] init];

l'errore che ottengo quando provo ad aggiungere il coppia chiave-valore è:

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

Accade perché non posso memorizzare UIButton * come chiavi? Qualcuno può indicarmi perché sto ricevendo questo errore? Grazie a tutti,

aa

risposta

3

Da Apple docs:

La chiave viene copiata (utilizzando copyWithZone :; chiavi devono essere conformi alle il protocollo NSCopying).

UIButton non è conforme al protocollo NSCopying e quindi non si può usarlo come una chiave nella NSDictionary

+0

Questo è quello che ho pensato, così hai qualche suggerimento su come risolvere questo problema? Dato un UIButton, ho bisogno di ottenere la classe personalizzata che rappresenta il pulsante. Se non riesco a usare un dizionario, ci deve essere un altro modo per farlo. Non posso usare un array perché diversi UIButtons possono riferirsi allo stesso oggetto. C'è un modo per dare al pulsante l'id della classe che rappresenta? O qualcosa di simile? –

16

Un modo che ho trovato è stato quello di utilizzare costruire un NSValue da utilizzare come chiave. Per creare l'utilizzo:

[NSValue valueWithNonretainedObject:myButton].

L'avvertimento qui sembra essere che se il pulsante è garbage collector, la chiave manterrà un riferimento non valido.

È possibile ottenere il riferimento al UIButton nuovo mentre scorrendo il Dizionario in questo modo:

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

Anche io sto affrontando lo stesso problema. Potresti spiegare come implementare questo trucco. Ho provato a farlo: - ma l'app si sta bloccando. \t \t NSDictionary * catPassdict = [dizionario NSDictionary]; \t \t \t \t \t [catPassdict setValue: [valore NSValoreWithNonretainedObject: catAppButton] forKey: @ "btn"]; – Gypsa

2

ho un trucco fresco per questo.

Lancio il puntatore a un int (poiché tutto ciò che è realmente un puntatore) e lo memorizza in un NSNumber. L'utilizzo di NSNumber come chiave risolve questo problema e ha senso in senso lato perché a chi importa memorizzare una copia del pulsante nel dizionario? Ha più senso per me memorizzare una copia delle informazioni del puntatore.

Se ti piaccio, probabilmente lo trasformerai in una macro. Qualcosa di simile a questo:

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

Allora è un po 'più pulito da usare nel codice ...

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

e un bel trucco per te: usa il mark-up incorporato fornito nel modulo invece dei tag html. – vikingosegundo

2

UIButtons hanno una proprietà description che può essere utilizzato come chiave del dizionario:

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

Se ci sono più UIButton usati come chiavi nel dizionario, c'è qualche garanzia che ognuno avrà un valore unico e immutabile per il suo valore di proprietà descrittivo? (Ho provato ad adottare questo approccio e ad impostare il valore della proprietà description, ma è di sola lettura.) –

+0

Ho usato questa soluzione con più UIButton e funziona perfettamente. Nel mio caso, non è necessaria alcuna descrizione personalizzata. – synthresin

Problemi correlati