Common Queue; una semplice soluzione

In ambienti asincroni, dove chiamate a metodi o rilascio di eventi sono pane quotidiano (vedi Adobe ActionScript o Objective-C), spesso la stessa sequenza di operazioni non è identica al millesimo di secondo. Inoltre più metodi posso chiamare una funzione più generale con il rischio di annulare l’una l’effetto dell’altra.

Per chiarire il concetto un esempio lampante. In ambiente iPhone si usa spesso attivare l’indicatore di rete sulla barra di stato, per indicare che c’è – appunto – “traffico” di rete, cioè si sta eseguendo un’operazione di download o upload (scaricamento o invio dati).

L’indicatore lo si attiva con:

1
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

La procedura che attiva tale indicatore dovrebbe anche disattivarlo quando l’operazione di rete è terminata:

1
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

Ora se due diverse procedure attivano e disattivano l’indicatore di stato, potrebbe verificarsi il caso in cui l’una contiene una chiamata all’altra. Quello che potrebbe capitare (anzi, capita se non si inseriscono determinati accorgimenti e controlli) è che chi finisce prima, disattiva l’indicatore, anche se l’operazione di rete – dell’altra – è ancora attiva!

Basandoci sul solo stato dell’indicatore non avremmo molte informazioni; nel senso che possiamo sapere se è attivo o no ma non se lo devo disattivare o no. Quello che serve, invece, è un flag che indichi se c’è qualche altra operazione “pending” – in corso.
In definitiva un sistema di code (queue) in grado di regolamentare questo accavallarsi di “accensioni” e “spengimenti”.

E bene, realizzare tale sistema è più semplice di quello che si potrebbe pensare in un primo momento. Nel caso esposto sopra basta infatti creare un seplice contatore globale, che viene incrementato ogni qualvolta qualcuno accende l’indicatore di rete e decrementato quando qualcuno lo disattiva.

Tradotto in codice, avremmo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Contatore globale per gestire la coda
int queueCount = 0;

// Metodo per attivare l'indicatore di rete
// In questo non effettuo nessun controllo particolare in quanto
// se l'indicatore è già attivo, riattivandolo non creo nessun danno
- (void)showActivityIndicator {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    queueCount++;
}

// Metodo per disattivare l'indicatore
// In questo caso - invece - decremento il mio contatore queueCount
// e disattivo l'indicatore solo quando queueCount è uguale a 0, cioè
// quando "tutti" hanno terminato il loro lavoro sulla rete
- (void)hideActivityIndicator {
    queueCount--;
    if (queueCount == 0) {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    }
}

Questa tecnica può essere utile anche in altri casi, come ad esempio sequenze di animazioni, download di pacchetti, sincronizzazione audio/video nei giochi, etc… Insomma, facile da ricordare, semplicissima da implementare!

Non ci sono commenti per questo Post

Lascia un commento

TAG XHTML PERMESSI: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> INSERIMENTO CODICE:
<pre></pre> // blocco generico
					<code></code> // blocco generico
					[cc_actionscript][/cc_actionscript] // Actionscript
					[cc_actionscript3][/cc_actionscript3] // Actionscript 3
					[cc_css][/cc_css] // CSS Style Sheet
					[cc_html][/cc_html] // HTML
					[cc_js][/cc_js] // Javascript
					[cc_objc][/cc_objc] // Objective-C
					[cc_php][/cc_objc] // PHP
					[cc_sql][/cc_sql] // SQL


Stop SOPA