Mentre il passaggio vista sulla barra di navigazione, come smettere di discussione NSOperationQueue in modo sicuro senza errori EXC_BAD_ACCESS
-
18-09-2019 - |
Domanda
Se si utilizza un'UITableView per mostrare alcuni messaggi di stringa, e io uso NSOperationQueue di tenere un NSOperation personalizzata che fetchs messaggio nel thread in background. Dopo un messaggio recuperato con successo, NSOperation personalizzato notificherà il controller UITableView di mostrarlo.
Se clicco di nuovo pulsante sulla barra di navigazione per passare dalla UITableView a altra vista, dopo tutto il messaggio caricato, ogni cosa è OK. Ma, se si fa clic sul pulsante Indietro mentre qualche messaggio ancora carica, un EXC_BAD_ACCESS è un tiro. Ho controllato che l'eccezione è successo mentre personalizzato NSOperation notificare regolatore UITableView con metodo performSelectorOnMainThread
. Suono come il controller di destinazione UITableView non è valido dopo vista acceso, ma penso Navigation Controller terrà l'istanza View Controller. Posso sapere come risolvere questo problema? Grazie.
operazione misura è inizializzata nel controllore UITableView con codice seguente:
StatusMessageLoadingOperation *operation = [[StatusMessageLoadingOperation alloc]
initWithData:person
messageArray:cachedStatusMessages
target:self
action:@selector(didFinishStatusMessages:)];
[operationQueue addOperation:operation];
[operation release];
La classe NSOperation misura aggiornerà UITableView con codice seguente:
- (void)main{
for (int i = 0; i < [[person statusMessages] count]; i++) {
[target performSelectorOnMainThread:action withObject:messageArray waitUntilDone:NO];
}
}
Soluzione
Hai provato a chiamare [operationQueue cancelAllOperations]
nel metodo viewWillDisappear
?
Altri suggerimenti
A causa schioccare un controller di vista richiama il metodo -dealloc
che del controllore, si può essere liberando la coda troppo presto, e qualche altra parte della vostra applicazione sta tentando di accedere alla coda o un'operazione al suo interno che non esiste più.
La mia raccomandazione è quella di mettere l'istanza NSOperationQueue *myQueue
nella vostra delegato applicazione.
Utilizzare -applicationDidFinishLaunching:
e -dealloc
metodi l'applicazione del delegato per inizializzare e rilasciare la coda e il suo contenuto.
Separando la coda dal controller della vista, la coda non sarà possibile ottenere rilasciata quando si pop fuori un controller vista dal vostro stack di spostamento. Si e ogni operazione rimanenti dovrebbe essere ancora a disposizione del resto dell'applicazione.
Per rendere più facile l'accesso coda, impostare la seguente definizione di macro:
#define UIAppDelegate ((MyAppDelegate *)[UIApplication sharedApplication].delegate)
È quindi possibile utilizzare la macro per accedere al tuo coda nel modo seguente, per esempio:.
NSLog(@"%@", [[UIAppDelegate myQueue] operations]);
O, per esempio:
[[UIAppDelegate myQueue] addOperation:myOperation];