• Programmazione Android
  • CORSI ONLINE
  • Web Agency

Logo

Corsi di programmazione web e mobile online
Navigation
  • Home
  • CORSI ONLINE
  • Tutorial Pratici
  • GUIDE COMPLETE
    • Corso completo di C
    • Corso videogame con Cocos2d
    • Programmazione Cocoa Touch
  • Sezioni
    • Libri e manuali
    • Tips & Tricks
    • Risorse utili
    • Strumenti di Sviluppo
    • Materiale OpenSource
    • Framework
    • Guide Teoriche
    • Guide varie
    • Grafica e Design
    • iPad
    • News
    • Video Tutorial
    • Windows Phone
  • Pubblicità
  • About
    • Chi siamo
    • Pubblicazioni
    • Collabora
    • Sostieni devAPP

T#068 – Progress view ed esecuzione di task in background

By Luca Di Franco | on 31 Agosto 2010 | 4 Comments
Senza categoria

T068 - Progress view esecuzione di task in background iphone Ad essere sincero non credevo di trovar un momento per realizzare due tutorial durante questa estate, limitiamoci a dire che rompersi lo zigomo proprio nel bel mezzo di agosto significa avere un mucchio di tempo libero seduto su un letto d’ospedale. E quale miglior modo per passare il tempo se non scrivendo un paio di tutorial per voi?

Bene in questo primo tutorial volevo parlare delle progress bar e come fare ad aggiornarle mostrando sullo schermo del nostro terminale quanto manca alla conclusione di alcuni task particolarmente dispendiosi in termini di tempo. Può sembrare un lavoro da poco, ma al contrario di quello che inizialmente può sembrare, presenta alcune insidie.

Credo che tutti sapete come creare una view based application e di aggiungere una progress view tramite Interface Builder, ma visto che il tempo non mi manca, ne perderò un po’ per spiegarlo anche a quelli di voi che si sono appena avvicinati alla programmazione per iPhone e magari non hanno ancora acquisito dimestichezza con questo strumento.

Una volta creato tramite Xcode il nostro progetto per un’applicazione iPhone view based chiamata, per esempio, ProgressBar (ok lo so di non avere molta fantasia nei nomi 🙂 ) apriamo il nostro ProgressBarViewController.h e aggiungiamo un riferimento che ci permetterà di accedere alla progress view. A questo scopo modifichiamo il file come segue andando quindi ad aggiungere un puntatore a quella che sarà la nostra progress view:

@interface ProgressBarViewController : UIViewController {
	IBOutlet UIProgressView *progressBar;
}

@end

Fatto questo non dobbiamo far altro che aprire con Interface Builder il file ProgressBarViewController.xib, aggiungere una progress view prendendola dalla library, trascinarla nella posizione in cui vogliamo metterla e collegarla alla variabile che abbiamo appena creato nel modo che possiamo vedere in figura:


Operazione da eseguire in Interface Builder

Ora possiamo passare al tutorial vero e proprio. Cominciamo col creare una funzione che simulerà una massiccia elaborazione di dati. Ipotizziamo per esempio 100 task della durata di 0.1 secondi ciascuno. La nostra funzione apparirà come segue:

- (void)heavyDataProcessing {
  NSInteger numberOfTasks = 100;
    for (NSInteger tasksDone = 0; tasksDone <= numberOfTasks; tasksDone++) {
      [NSThread sleepForTimeInterval:0.1];
      NSNumber *progress = [[NSNumber alloc] initWithFloat:((float)tasksDone / (float)numberOfTasks)];
      [progress release];
    }
}

Per ora ci limitiamo a memorizzare il valore di progresso che abbiamo raggiunto nell’esecuzione dei vari task in un NSNumber perché prima di scrivere le istruzioni per eseguire il nostro heavyDataProcessing e di modificare la progress view abbiamo bisogno di un paio di nozioni che vado adesso a spiegare nella maniera più semplice possibile.

Nel thread principale viene eseguito il main run loop che si preoccupa di catturare gli eventi (i più comuni sono i tocchi sullo schermo). Quello che interessa a noi però è che anche la modifica al valore che la progress view deve visualizzare rappresenta un evento. Una volta che il main run loop riceve un evento questo lo passa all’UIResponder più opportuno (ovvero la nostra UIProgressView, che eredita da UIView che a sua volta eredita da UIResponder) che lo gestirà, nel nostro caso verrà ridisegnando la progress view con il valore aggiornato. Ora se noi invochiamo il metodo heavyDataProcessing normalmente, questo verrà eseguito nel main thread. Verrà quindi bloccata l’esecuzione del run loop per permettere l’esecuzione del metodo. Questo fatto che a prima vista ci sembra una stupidata ha un effetto piuttosto micidiale. Niente run loop significa niente gestione degli eventi che nel nostro caso si traduce in nessun update del valore visualizzato dalla nostra progress bar (che verrà aggiornata solo al termine della funzione). Per ovviare a questo problema ci basta ricorrere ad un piccolo espediente: eseguiamo la funzione per il data processing in un thread secondario chiamato background thread limitandoci ad eseguire nel main thread solo la semplice e di rapida esecuzione funzione per l’update della progress bar.
Vediamo ora come.

Cominciamo invocando il metodo nel Background thread. Per far ciò ridefiniamo il metodo viewDidLoad (in questo modo siamo anche sicuri che la progress view è stata creata).

- (void)viewDidLoad {
   [self performSelectorInBackground:@selector(heavyDataProcessing)
                          withObject:nil];
}

Ora la nostra funzione heavyDataProcessing verrà eseguita in un thread separato. Per poter far funzionare il tutto correttamente, ci mancano ancora due passaggi:

  1. Scrivere la funzione che aggiornerà la progress view (da eseguire nel main thread).
  2. Aggiungere la chiamata a questa funzione nella heavyDataProcessing.

Cominciamo con scrivere la funzione:

- (void)updateProgressBar:(NSNumber *)progress {
	progressBar.progress = [progress floatValue];
}

Si tratta di una semplicissima funzione che prende come parametro il valore attuale di progresso della progress bar e glielo assegna.

Andiamo ora a modificare la funzione heavyDataProcessing come segue:

- (void)heavyDataProcessing {
   NSInteger numberOfTasks = 100;
   for (NSInteger tasksDone = 0; tasksDone <= numberOfTasks; tasksDone++) {
      [NSThread sleepForTimeInterval:0.1];
      NSNumber *progress = [[NSNumber alloc] initWithFloat:((float)tasksDone / (float)numberOfTasks)];
      [self performSelectorOnMainThread:@selector(updateProgressBar:) withObject:progress waitUntilDone:NO];
      [progress release];
   }
}

Come possiamo vedere ci siamo limitati ad a aggiungere la riga numero 6 che ci permette di far eseguire la funzione updateProgressBar nel main thread, passando come parametro il nuovo valore da assegnare alla progress bar (valore che abbiamo calcolato e salvato nell’NSNumber).

Perfetto! Ora tutto dovrebbe funzionare a dovere. Premete su Build and Run e godetevi la progress bar che a poco a poco si riempie.

Come tutte le altre volte, anche il codice di questo tutorial lo trovate hostato su Google Code.


T068 - Progress view esecuzione di task in background iphone

Share this story:
  • tweet

Tags: developer iphoneInterface BuilderiphoneLuca di FrancoObjective-cprogrammazioneprogrammazione iphoneprogress barprogress viewteoriatutorialTutorial Praticiuiprogressview

Recent Posts

  • Parte il percorso programmatori iOS in Swift su devACADEMY.it

    20 Dicembre 2017 - 0 Comment
  • Android, crittografare dati velocemente con Encryption

    24 Settembre 2018 - 0 Comment
  • Sql2o, accesso immediato ai database tramite Java

    3 Settembre 2018 - 0 Comment
  • Okio, libreria per ottimizzare l’input/output in Java

    27 Agosto 2018 - 0 Comment

Related Posts

  • Microservizi per logiche applicative di grandi dimensioni

    27 Luglio 2016 - 0 Comment
  • Uno sguardo al runtime Objective-c

    10 Settembre 2013 - 0 Comment
  • Andrea Picchi: Programmare con Objective-C 2.0 per iOS e OS X

    27 Febbraio 2013 - 10 Comments

Author Description

4 Responses to “T#068 – Progress view ed esecuzione di task in background”

  1. 31 Agosto 2010

    Tweets that mention T#068 - Progress view ed esecuzione di task in background | devAPP -- Topsy.com

    […] This post was mentioned on Twitter by Rynox, devAPP. devAPP said: T#068 – Progress view ed esecuzione di task in background http://bit.ly/9ndSH4 […]

  2. 16 Settembre 2010

    Bruno

    Oh, quanto mi dispiace per il tuo zigomo! Qualche hanno fa ruppi il polso, 4 ore di lavoro prima di andarmene in ferie 3 settimane, ovvero ESATTAMENTE il tempo di rimuovere il gesso…
    Puoi immaginare quanti bagni in piscina ho fatto….. che sfiga…
    Tanti auguri di pronta guarigione, recupererai l’hanno prossimo!
    PS. Ma si può sapere come hai fatto? Moto, calcio, rissa o hai detto alla morosa che era ingrassata?? :o)

  3. 17 Settembre 2010

    Luca Di Franco

    E’ successo tutto con una classica craniata giocando a calcio. Fosse stata la morosa non me la sarei cavata con così poco 😛

  4. 19 Settembre 2011

    Ale

    Ciao, utilissima guida, grazie.

    Ho una variante da sottoporti.

    Nel controller di una view ho una var di istanza della mia cSync.

    Alla pressione di un pulsante eseguo oSync.exec che impiega una decina di secondi per essere eseguito.

    OSync.exec scatena un evento al suo avvio e uno al termine, nel controller della view (suo delegato)

    In questi due eventi rendo una progresso bar = no e = yen.

    Il problema è che, come hai decritto nell’articolo, fino a quando non è terminata l’esecuzione del metodo oSync.exec non viene eseguito neanche il codice dell’evento start, scatenato all’inizio.

    Se non sono stato chiaro posto il codice ridotto di un esempio del caso.

    Ciao

Leave a Reply

Your email address will not be published. Required fields are marked *


*
*

Corso online di programmazione android e java

SEZIONI

  • Android
  • Comunicazioni
  • Contest
  • Corsi ed Eventi
  • Corso completo di C
  • Corso programmazione videogiochi
  • Framework
  • Grafica e Design
  • Guida rapida alla programmazione Cocoa Touch
  • Guide Teoriche
  • Guide varie
  • iPad
  • Le nostre applicazioni
  • Libri e manuali
  • Materiale OpenSource
  • News
  • Pillole di C++
  • Progetti completi
  • Risorse utili
  • Strumenti di Sviluppo
  • Swift
  • Tips & Tricks
  • Tutorial Pratici
  • Video Tutorial
  • Windows Phone

Siti Amici

  • Adrirobot
  • Allmobileworld
  • Apple Notizie
  • Apple Tribù
  • Avvocato360
  • Blog informatico 360°
  • bubi devs
  • fotogriPhone
  • GiovaTech
  • iApp-Mac
  • iOS Developer Program
  • iPodMania
  • MelaRumors
  • Meritocracy
  • SoloTablet
  • TecnoUser
  • Privacy & Cookie Policy
©2009-2018 devAPP - All Rights Reserved | Contattaci
devAPP.it è un progetto di DEVAPP S.R.L. - Web & Mobile Agency di Torino
Str. Volpiano, 54 - 10040 Leini (TO) - C.F. e P.IVA 11263180017 - REA TO1199665 - Cap. Soc. € 10.000,00 i.v.

devACADEMY.it

Vuoi imparare a programmare?

Iscriviti e accedi a TUTTI i corsi con un’unica iscrizione.
Oltre 70 corsi e migliaia di videolezioni online e in italiano a tua disposizione.

ISCRIVITI SUBITO