• 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

L#019 – Comunicazione tra oggetti: Notifiche e Delegati in Objective-C

By Gianluca Tranchedone | on 25 Luglio 2011 | 8 Comments
Guide Teoriche

Ciao a tutti. Oggi voglio parlarvi di un aspetto molto importante nella programmazione ad oggetti e che ha un’inestimabile valore anche nella programmazione per iOS: la comunicazione tra oggetti.

Quando si ha a che fare con oggetti di varia natura, ci può capitare di voler far comunicare alcuni di essi per ottenere specifiche funzionalità. Solitamente, saremo noi stessi a creare una serie di classi che secondo la nostra architettura sono specificatamente progettati per comunicare tra loro. A questo proposito l’Objective-C ci mette a disposizione vari strumenti, ma due di essi sono i più comuni in tutti i progetti e negli stessi SDK forniti da Apple per la programmazione per iOS e Mac OS: notifiche e delegati.

Inviare e Ricevere Notifiche

Un modo molto semplice ed efficace per mettere in relazione due o più oggetti senza che essi debbano conoscere alcun che dell’altro o degli altri, è la classe NSNotificationCenter, che ci permette di far inviare e ricevere messaggi da e verso il centro notifiche di questa classe (che è un Singleton), ed eseguire azioni di conseguenza.

Il concetto fondamentale è che la classe NSNotificationCenter si pone come intermediario tra i nostri oggetti per favorirne la comunicazione. Il NotificationCenter raccoglie le notifiche che gli oggetti inviano e le invia agli oggetti che si sono registrati per riceverle. Un’oggetto, infatti può registrarsi presso il centro notifiche per ricevere una o più notifiche. Inoltre più oggetti possono registrarsi per ricevere la stessa notifica, il che rende ancora più utile questo strumento. Quando un’oggetto si registra per ricevere una notifica, può decidere di far effettuare ad un certo target un’azione (invocando un metodo del target, quindi).

Per registrare un oggetto al ricevimento di una notifica basta una linea di codice:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(unMetodo) name:@"Nome della notifica" object:nil];

Con questo comando, otteniamo l’oggetto Singleton “defaultCenter”, quindi registriamo l’oggetto come osservatore di notifiche per la notifica il cui nome indichiamo nel parametro “name” (ma possiamo registrare come osservatore anche un oggetto che self contiene, ad esempio una sua variabile d’istanza) e indichiamo il metodo che va invocato quando l’osservatore riceve la notifica. Nel parametro “object” possiamo specificare un oggetto come mittente della notifica. In pratica, se una stessa notifica può essere inviata da più oggetti, possiamo decidere che un’osservatore effettui l’azione prevista solo se il mittente della notifica è un determinato oggetto.

Registrare un oggetto come osservatore per fargli ricevere notifiche è dunque un processo molto molto semplice. Altrettanto semplice è inviare una notifica al centro notifiche:

[[NSNotificationCenter defaultCenter] postNotificationName:@"Nome della Notifica" object:nil userInfo:nil];

Ancora una volta otteniamo l’oggetto Singleton “defaultCenter” e pubblichiamo una notifica con un dato nome. Possiamo aggiungere poi variabili addizionali, object (cioè il mittente della notifica) e userInfo (un dizionario con le informazione dell’utente).

NOTA: è consigliabile usare delle costanti come nomi per le notifiche in modo tale da evitare errori di scrittura nel codice e rendere più agevole la modifica del nome della notifica in un secondo momento. Infatti, se volessimo cambiare il nome della notifica, in questo modo lo dovremmo fare solo una volta, nel file dove la costante è stata dichiarata, mentre quando andiamo a scrivere il nome della costante come parametro per i metodi usati dal notificationCenter, non trattandosi di una stringa, il compilatore ci avvertirà della presenza di eventuali errori di battitura.

Delegare non è un male!

L’uso delle notifiche rende molto più semplice la vita di noi poveri sviluppatori. D’altro canto, però, inviare notifiche può rivelarsi insufficiente per i nostri scopi. Ci ritroveremo allora nella condizione in cui delegare alcune azioni ad altri oggetti sia una pratica migliore. Questo accade specialmente quando vogliamo far si che una classe implementi dei metodi che permettano l’uso di un componente che abbiamo creato. In particolare, questa pratica si rivela utilissima quando chi userà il nostro componente non siamo noi, o quando il nostro componente può essere usato in tante classi diverse e a scopi diversi. Un’esempio di classe che è solita delegare ad altri aggetti alcune azioni è la classe UITableViewController, che delega alle sue sottoclassi il compito di fornire una fonte per le informazioni da mostrare nelle celle e di definire alcuni comportamenti delle celle (ad esempio, definire cosa succede quando una data cella viene selezionata).

È pratica comune definire i metodi da delegare nell’intestazione della classe che richiama il suo delegato per eseguire una data azione. Delegare dei metodi da implementare ad un’altro oggetto, implica anche definire quali sono questi metodi. Per farlo viene usata la parola chiava @protocol. Se ad esempio abbiamo una classe Box (Scatola) che vuole delegare al suo utente un metodo per definire cosa c’è nella scatola, la sua dichiarazione e implementazione saranno qualcosa del tipo:

@protocol BoxDelegate; // dichiara che esiste un protocollo chiamato BoxDelegate

@interface Box : NSObject 
{
    id delegate_; // scrivere tra parentesi angolari il nome di un protocollo subito dopo il tipo di una variabile, significa dichiarare che quella variabile deve conformarsi al dato protocollo (cioè adottarne i metodi)
}

@property (nonatomic, retain) id delegate;

- (void)riempiScatola;

@end

@protocol BoxDelegate  // definiamo i metodi che compongono il protocollo

- (NSArray *)inserisciOggetti;

@optional
- (void)svuotaScatola;

@end

Nell’interfaccia di questa classe definiamo il protocollo con due metodi. I metodi che indichiamo nel protocollo, normalmente sono da implementare obbligatoriamente all’interno del delegato, ma possiamo decidere di rendere l’implementazione di alcuni di essi facoltativa dichiarandoli dopo la parola chiave @optional. La variabile delegate che abbiamo definito, deve conformarsi al protocollo, quindi implementarne i metodi obbligatori.

Una possibile implementazione del metodo d’istanza della classe Box “riempiScatola”, potrebbe essere:

- (void)riempiScatola
{
    NSArray *oggetti = [NSArray arrayWithArray:[self.delegate oggettiNellaScatola]];
    // riempi la scatola
}

Per implementare i metodi di un protocollo in una classe, dobbiamo dichiarare che la classe si conforma al dato protocollo. Per far ciò ci basta scrivere nell’intestazione della classe, subito dopo il nome della sua superClasse, il nome del protocollo fra parentesi angolari ““. Se una classe si conforma a più protocolli, i nomi di questi protocolli vanno scritti tra parentesi angolari separati da virgola. Ad esempio:

@interface MyBox : UIViewController 

Questa classe ovviamente dovrà dichiararsi come delegato per un protocollo anche con un’istruzione del tipo:

Box *laMiaScatola = [[Box alloc] init];
laMiaScatola.delegate = self;

e ricordatevi di implementare opportunamente i metodi dichiarati nel protocollo come obbligatori!

Conclusioni

Mettere in comunicazione più oggetti senza far interagire troppo una classe con un’altra non è un compito semplice ma per fortuna i design patterns di delegazione e notifica ci vengono in aiuto. Questi non sono gli unici metodi per far comunicare più oggetti fra loro ma sono i più semplici e utili. Per un’ancora più efficace comunicazione tra due o più oggetti potreste utilizzare tranquillamente entrambi i metodi, delegando azioni e notificando eventi che ne inneschino altre.

Che dire di più? Divertitevi a far comunicare tra loro i vostri oggetti! 🙂

Share this story:
  • tweet

Tags: Comunicazione tra oggetti OOPDelegare XCodeDelegate Objective-CDelegati Objective-CNSNotificationCenterprogrammazione ad oggettisingleton

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

  • T#109 – Key-Value Observing: Costruiamo un semplice lettore multimediale

    22 Maggio 2012 - 8 Comments
  • L#020 – Far comunicare oggetti diversi in Objective-C: quale metodo scegliere?

    3 Novembre 2011 - 5 Comments
  • T#076 – Utilizziamo una classe esterna per passare oggetti tra viste differenti

    18 Ottobre 2010 - 20 Comments

Author Description

Gianluca lavora come iOS Developer presso una nota azienda Nederlandese. Nonostante si sia laureato in Lingue Culture Comparate (Giapponese e Anglo-Americana) presso l'Università degli Studi di Napoli “L'Orientale”, la passione per la programmazione risale all'età della fanciullezza in cui aveva imparato i rudimenti del C++. L'interesse per questa materia è però andato oltre questa base solo dalla fine del 2009, quando si è avvicinato alla programmazione per iPhone. A Settembre 2010 ha comprato il suo primo Mac (finalmente) e ha iniziato a programmare la sua prima app per iPhone, “Japanese Grammar Dictionary: Basic”, disponibile da metà Gennaio 2011 su App Store. Nel Luglio dello stesso anno, la sua seconda applicazione, “Chi Paga da Bere?”, è stata pubblicata sull'App Store.

8 Responses to “L#019 – Comunicazione tra oggetti: Notifiche e Delegati in Objective-C”

  1. 25 Luglio 2011

    Giovambattista Fazioli

    Per dettagli:
    http://www.undolog.com/2011/03/10/objective-c-notifiche-e-delegati/

  2. 25 Luglio 2011

    Andrea Cappellotto

    se devo essere sincero questo articolo non mi piace per niente…. preferisco molto di più quello linciato da Giovambattista….

  3. 25 Luglio 2011

    Ignazioc

    che sei aspro! 🙂 diciamo che forse non è chiarissimo per una persona alle prime armi, su questo ti do ragione..

  4. 25 Luglio 2011

    Andrea Cappellotto

    il correttore di Lion mi ha preso alla lettera..:) linciato al posto di linkato..:) e poi era da un mese che appena riproponevo che appena finite le app urgenti facevo un tut sui delegati…;)

  5. 2 Agosto 2011

    Giuseppe

    Concordo con i commenti precedenti. Apprezzo moltissimo il lavoro che state facendo e continuerò a seguirvi, ma questo capitolo è stato poco chiaro. Sarebbe meglio inserire alcuni esempi costruiti passo passo.

  6. 4 Agosto 2011

    ultrakorne

    è un argomento molto importante, e i delegate se uno non è pratico possono essere ostici, hanno bisogno di un analisi più approfondita.

    Consiglierei di trattarli insieme all MVC così da far capire bene il bisogno del delegate, e la differenza con le notifications (e magare citare il KVO).

    poi un errore:
    @property (nonatomic, retain) id delegate;

    bisognerebbe tenere un weak reference al delegate (quindi assign non retain). facendo retain si rischia un retain ciclico dove 2 oggetti si trattengono a vicenda.

  7. 17 Giugno 2012

    Objective C Delegate | CianiAndreaDev

    […] http://www.devapp.it/wordpress/l019-comunicazione-tra-oggetti-notifiche-e-delegati-in-objective-c.ht… […]

  8. 16 Giugno 2013

    Andrea

    Un altro tutorial dettagliato lo potete trovare QUI

    http://www.cianiandrea.it/archives/413

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