2012-04-11 4 views
10

Qual è il modo corretto di allegare e rimuovere un UIGestureRecognizer su una vista?Modo corretto di collegamento/rimozione di UIGestureRecognizers

Generalmente creo e allega UIGestureReconizers in -viewDidLoad. Devo usare removeGestureRecognizer nello -viewDidUnload? Oppure vengono rimossi automaticamente?

per esempio, è un modo migliore per creare una proprietà UIGestureRecognizer e inizializzare nel metodo init del viewController e quindi collegare/rimuovere questa proprietà gestureRecognizer in -viewDidAppear/-viewDidDisappear?

(Nota Sto usando ARC)

Grazie.

+0

L'ho già sfogliato ma non ho trovato la risposta alla mia domanda. – mrd3650

+0

@TheLion: "Mi dispiace, quella pagina non può essere trovata." – Colas

+0

Spiacenti Apple lo ha modificato, quindi [qui] (https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizer_basics/GestureRecognizer_basics.html) è il nuovo URL per la stessa risorsa. Grazie per il tuo commento @Colas –

risposta

10

In sostanza è possibile creare, aggiungere e rimuovere i riconoscitori di gesti quando ha senso. E "quando ha senso" varia a seconda di alcune cose, ma di solito solo se le manterrai come ivar. Con ARC la chiave gestisce i riferimenti forti; Con i valori ARC, i predefiniti sono forti.

Quindi supponiamo di aggiungere un tocco di riconoscimento. In questo scenario non è necessario accedere nuovamente al riconoscimento. Lo creerei in questo modo:

-(void)viewDidLoad{ 
    [super viewDidLoad]; 
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; 
    [self.view addGestureRecognizer:tap]; 
} 

Con questo scenario, non è necessario fare nient'altro per gestire questo riconoscimento. Il sistema di visualizzazione ha un forte riferimento ad esso. Tutto quello che fai è sedersi e aspettare che chiami handleTap:. Quando la vista viene scaricata, questo indicatore di riconoscimento verrà deallocato.

Questo scenario non sarebbe positivo se si aggiunge questo riconoscimento in viewWillAppear: poiché non è difficile immaginare una serie di eventi che potrebbero portare alla creazione di più riconoscitori.

Quindi, logicamente, se si desidera aggiungere un riconoscitore nei metodi di aspetto si dovrebbe tenere un qualche tipo di riferimento ad essi in un ivar. Ma ancora una volta non è sempre una cattiva idea. In genere, il motivo per cui si desidera fare riferimento ai propri riconoscitori è di aiutare nella logica dei metodi <UIGestureRecognizerDelegate>, se vengono utilizzati.

Personalmente non aggiungerei mai un riconoscimento nel metodo initWith.. per l'allegato successivo. L'unico vantaggio è che qualsiasi strumento di riconoscimento creato dall'utente verrà mantenuto per l'intera durata del controller di visualizzazione. Ma dal momento che un riconoscitore è chiaramente parte del sistema di visualizzazione di questo tipo di fangosi, il MVC su cui Cocoa è grande. Inoltre, in una condizione di memoria insufficiente, la vista dei controller sullo stack di navigazione viene eliminata, ma in questo caso il riconoscitore potrebbe rimanere utilizzando la memoria (non gli enormi oggetti) senza una vera ragione.

È possibile aggiungere un riconoscimento in un metodo view(Will/Did)Appear: e rimuoverlo in view(Will/Did)Disappear:. Non la mia preferenzaNon penso che solo perché una vista modal è presentata e rimossa o è stata eseguita una navigazione push/pop che dovrei rimuovere e riaggiungere i miei riconoscitori.

Suggerirei quasi sempre di utilizzare viewDidLoad per creare un'istanza e collegare i propri riconoscitori. Basta ricordare di non avere alcun riferimento forte a loro in viewDidUnload per aiutare in una situazione di memoria insufficiente. E ancora con ARC non è necessario fare nulla con ivars in dealloc.

+0

Grazie NJones per la risposta dettagliata! Il motivo per il collegamento/scollegamento dei Riconoscitori in Visualizza (sarà/fatto) Load and Unload era puramente per motivi di memoria (in modo che quando la vista non è sullo schermo, la memoria è rilasciata e assegnata quando è sullo schermo) ma da quello che dici , non fa molta differenza. – mrd3650

0

viewDidUnload viene chiamato solo in condizioni di memoria insufficiente e non è garantito che venga chiamato. Pertanto, qualsiasi riconoscitore di gesti rimosso in viewDidUnload deve essere rimosso anche in dealloc. L'altro metodo che hai menzionato va bene.

0

ok poi viewWillAppear:Animated e viewWillDisappear:animated sarà la scelta migliore per fare qualsiasi cosa con gesti come di mia conoscenza.