• 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#076 – Utilizziamo una classe esterna per passare oggetti tra viste differenti

By Andrea Cappellotto | on 18 Ottobre 2010 | 20 Comments
Senza categoria

Ciao a tutti, come promesso sul Forum oggi vi faccio vedere come utilizzare una classe esterna per passare oggetti tra viste. In particolare io la utilizzo sempre per creare le detailView delle UITableView.
L’idea di fondo è questa: realizzare una classe in cui sono presenti ufficialmente due metodi:

- impostaValore
- ottieniValore

La nostra classe verrà inizializzata la prima volta che la utilizziamo e poi basta, così da poterci accedere.

Iniziamo con il nostro progetto

Creaiamo un progetto “Navigation-Based”, che includerà già una tabella, e nel file .h definiamo un array e un viewController (ci servirà per passare alla vista dettagli)_

#import 

@interface RootViewController : UITableViewController 
{
	NSArray * arrayValori;
	UIViewController * temp;
}

@end

A questo punto passiamo al metodo “viewDidLoad” del file di implementazione .m e inizializziamo l’array:

- (void)viewDidLoad {
    [super viewDidLoad];
	self.title = @"Singleton";

    NSDictionary * dict1 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"iPhone 3G", @"Questo è un iPhone 3G", nil] 
													   forKeys:[NSArray arrayWithObjects:@"titolo", @"descrizione", nil]];

	NSDictionary * dict2 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"iPhone 3GS", @"Questo è un iPhone 3GS", nil] 
													   forKeys:[NSArray arrayWithObjects:@"titolo", @"descrizione", nil]];

	NSDictionary * dict3 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"iPhone 4", @"Questo è un iPhone 4", nil] 
													   forKeys:[NSArray arrayWithObjects:@"titolo", @"descrizione", nil]];

	NSDictionary * dict4 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"iPhone 5", @"Questo modello non esiste", nil] 
													   forKeys:[NSArray arrayWithObjects:@"titolo", @"descrizione", nil]];

	arrayValori = [[NSArray alloc] initWithObjects:dict1, dict2, dict3, dict4, nil];
}

Su ogni dizionario abbiamo inserito un valore per “titolo” e uno per “descrizione”  che visualizzeremo nella “detailView”.

Modifichiamo ora il metono “numberOfRowInSection” come segue:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [arrayValori count];
}

e nel metodo:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

inseriamo prima del “returm cell;” la seguente istruzione:

cell.textLabel.text = [[arrayValori objectAtIndex:indexPath.row] objectForKey:@"titolo"];

Proviamo ad eseguire sul simulatore. Dovremmo ottenere una tabella come questa:




La classe “singleton”

Andiamo ora su File -> New File e selezioniamo “Objective-c class”. Verifichiamo quindi che la classe erediti da “NSObject” (altrimenti impostiamolo noi a mano)

Chiamiamo questa classe “singleton”.

Ecco cosa dovremo inserire nel nuovo file .h:

@interface singleton : NSObject {

}

+ (void)impostaArray:(NSMutableArray *)valore;
+ (NSMutableArray *)ritornaArray;

+ (void)impostaItem:(NSMutableDictionary *)valore;
+ (NSMutableDictionary *)ritornaItem;

+ (void)impostaStringa:(NSMutableString *)valore;
+ (NSMutableString *)ritornaStringa;

@end

Abbiamo inserito 6 metodi, ogni coppia ci permetterà di settare e ottenere array, dictionary e stringhe.

Passiamo al file .m e definiamo quindi i metodi appena dichiarati:

NSMutableArray *arrayCondiviso;
NSMutableDictionary *itemCondiviso;
NSMutableString * stringaCondivisa;

static singleton *sharedClass = nil;

// Con questo metodo imposto il valore dell'item condiviso
+ (void)impostaArray:(NSMutableArray *)valore{
	arrayCondiviso = valore;
}

// Con questo metodo, prelevo il valore dell'item condiviso da qualsiasi classe
+ (NSMutableArray *)ritornaArray{
	return arrayCondiviso;
}

+ (void)impostaItem:(NSMutableDictionary *)valore{

	itemCondiviso = valore;
}

+ (NSMutableDictionary *)ritornaItem{

	return itemCondiviso;
}

+ (void)impostaStringa:(NSMutableString *)valore{
	stringaCondivisa = valore;
}

// Con questo metodo, prelevo il valore dell'item condiviso da qualsiasi classe
+ (NSMutableString *)ritornaStringa{
	return stringaCondivisa;
}

+ (singleton *)sharedManager
{
    @synchronized(self) {
        if (sharedClass == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedClass;
}

+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self) {
        if (sharedClass == nil) {
            sharedClass = [super allocWithZone:zone];
            return sharedClass;  // assignment and return on first allocation
        }
    }
    return nil; //on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain
{
    return self;
}

- (unsigned)retainCount
{
    return UINT_MAX;  //denotes an object that cannot be released
}

- (void)release
{
    //do nothing
}

- (id)autorelease
{
    return self;
}

Non preoccupatevi se non capite tutto il codice, vi basta sapere che la prima volta che utilizzate questa classe lei chiama il metodo “init” e vi permette di utilizzarla per impostare un oggetto.

La classe “detailView”

Fatto questo procediamo nel creare la vista dettaglio. Andate in File -> New File e creiamo una classe di tipo “UIViewController subclass” con rispettivo file .xib (ma che non erediti da UITableView) e chiamiamola “detailView”.

Ritorniamo un attimo al nostro RootViewController e nel metodo:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

Inseriamo il seguente codice:

[singleton impostaItem:[arrayValori objectAtIndex:indexPath.row]];

temp = [[detailView alloc] initWithNibName:@"detailView" bundle:[NSBundle mainBundle]];

[self.navigationController pushViewController:temp animated:YES];

[temp release];

temp = nil;

Ricordiamoci di importare nel “RootViewController.h” sia la classe “singleton.h” che la “detailView.h”

Passiamo alla classe detailView.h:

#import 
#import "singleton.h"

@interface detailView : UIViewController {
	UILabel * descrizione;
}

@end

Anche qui non abbiamo fatto altro che importare di nuovo la classe singleton e dichiarare un UILabel che conterra la nostra descrizione.

Mentre nel file .m allochiamo semplicemente la label e ne impostiamo il testo ottenuto dalla classe singleton in questo modo:

- (void)viewDidLoad 
{
    [super viewDidLoad];
	descrizione = [[UILabel alloc] initWithFrame:CGRectMake(50, 200, 300, 20)];
	descrizione.text = [[singleton ritornaItem] objectForKey:@"descrizione"];
	[self.view addSubview:descrizione];

}

Ecco qui il nostro progetto con il passaggio di variabili.. quello che dovete fare è semplicemente importare la classe, impostare il valore e poi ottenerlo.

Ogni oggetto resta impostato finchè non lo sovrascrivete, quindi potete anche richiamare piu volte

[singleton ritornaItem] 

se non l’avete modificata prima.

Ciao, alla prossima

Se avete problemi con il tutorial, questo è il nostro file di progetto.

Share this story:
  • tweet

Tags: Andrea Cappellottopassare oggetti tra viewsingletonTutorial Praticitutorial Xcode

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

  • Xcode 4: Distribuzione Ad Hoc delle applicazioni iPhone e iPad

    10 Gennaio 2012 - 20 Comments
  • Tutorial pratici per iOS SDK: disponibile la versione 2.0 aggiornata a iOS 5 e XCode 4.2

    16 Novembre 2011 - 6 Comments
  • L#020 – Far comunicare oggetti diversi in Objective-C: quale metodo scegliere?

    3 Novembre 2011 - 5 Comments

Author Description

Perito Elettrotecnico e studente di Scienze Informatiche presso l'università di Trento. Da inizio 2010 , dopo aver lavorato come sistemista-tecnico informatico, si occupa di programmazione in ambito iOS, collabora con un'azienda trentina nello sviluppo di applicazioni iOS per il turismo e realizza soluzioni personalizzate per aziende. Tra gli ultimi progetti ricordiamo l'integrazione tra iOS e Arduino segno che l'open source può benissimo lavorare con sistemi più chiusi come i device Apple! Per devAPP scrive tutorial sulla programmazione, da cosigli su strumenti da utilizzare per semplificare la programmazione, è inoltre moderatore del forum con all'attivo quasi mille post e partecipazioni giornaliere.

20 Responses to “T#076 – Utilizziamo una classe esterna per passare oggetti tra viste differenti”

  1. 18 Ottobre 2010

    Tweets that mention Utilizziamo una classe esterna per passare oggetti tra viste differenti | devAPP -- Topsy.com

    […] This post was mentioned on Twitter by raaden, Rynox and iPadWorld.it, devAPP. devAPP said: Utilizziamo una classe esterna per passare oggetti tra viste differenti http://bit.ly/agxwCa […]

  2. 18 Ottobre 2010

    stefano

    Ciao Andrea e grazie per il tutorial e la promessa mantenuta!
    Questo metodo è applicabile anche se l’array viene fatto dal parsing di un xml?
    Grazie!

  3. 18 Ottobre 2010

    Andrea Cappellotto

    certo, a qualsiasi tipo di array, che contiene qualsiasi cosa, e se utilizzi impostaItem e impostaStringa puoi utilizzare la classe anche per dizionari e stringhe

  4. 18 Ottobre 2010

    Gianluca

    In questo caso come si divide la tabella in sezioni? Ho provato ma al più sono riuscito a ottenere una tableview con le sezioni giuste ma che mostrava tutti gli elementi XD. Lo so che deve essere una ca***ta, non ci far caso, rispondimi semplicemente XD.

  5. 18 Ottobre 2010

    Andrea Cappellotto

    Ciao, per questa cosa ci conviene andare avanti nel forum, non è cosi facile come si pensa..:)

  6. 18 Ottobre 2010

    Gianluca

    Ok, ho appena postato una risposta al tread del tutorial 😉

  7. 18 Ottobre 2010

    stefano

    allora, seguendo i tutorial del forum avevo già parsato il mio xml… il metodo era tutto nella classe controller del del mio tableview controller.. adesso devo importare tutto nella mia nuova singleton giusto? in modo che li venga inizializzato e popolato il mio array… praticamente dovrei prendere le stesse cose e spostarle?
    e poi potrei riutilizzare l’array nella vista di dettaglio?

  8. 18 Ottobre 2010

    stefano

    Perfetto! Funziona tutto! Sono riuscito a implementare nel parser del mio array! Grande!

  9. 19 Ottobre 2010

    andrea

    perfetto:) mi fa piacere..:)

  10. 19 Ottobre 2010

    MacMomo

    Una domanda.
    Ma in questo modo non c’è il rischio che gli oggetti puntati dalla classe singleton vengano rilasciati a nostra insaputa?
    E che quindi puntino in realtà a zone ignote di memoria, causando dei possibili crash?

  11. 19 Ottobre 2010

    andrea

    rilasciati a nostra insaputa no, al massimo potresti perdere il dato se l’applicazione crasha inaspettatamente, ma durante un funzionamento normale puoi stare al sicuro

  12. 19 Ottobre 2010

    MacMomo

    Puoi stare al sicuro nel senso che il programmatore dovrebbe sapere dove e come usa certi metodi, quindi dovrebbe evitare di rilasciare nel frattempo gli oggetti assegnati tramite la classe singleton, ma se un’app è molto grande e complicata secondo me non è la soluzione più indicata. O almeno sarebbe da aggiungere un retain/release degli oggetti assegnati, per qualsiasi eventualità.
    Nell’esempio indicato tra l’altro non era più semplice aggiungere un metodo alla classe detailView che facesse assegnare direttamente i valore del label?

  13. 19 Ottobre 2010

    andrea

    sinceramnte non lo utilizzerei neanke io per un app troppo complicata, ma per due viste e per iniziare direi che è la cosa migliore, sopratutto per chi usa ancora interface builder… questo è solo un modo, aggiungere un metodo alla detailView è sicuramente la cosa migliore, ma nessuno vieta di fare così..

  14. 19 Ottobre 2010

    antonio

    non vedo l’utilità della cosa. Se devo passare un oggetto ad una vista di dettaglio uso le proprietà e con poche righe di codice ho lo stesso risultato con un controllo maggiore della memoria ed elimino il rischio di concorrenza sui valori degli attributi dell’oggetto in questione.

  15. 9 Novembre 2010

    Errivara

    Ciao andrea, sei sparito dal mondo?
    Il tuo blog non c’è più e ti ho pure inviato una mail a cui non rispondi;-)

    Ti prego mandami una mail a enricovara@hotmail.it che ti devo parlare di un progetto:-)

  16. 15 Novembre 2010

    Marco

    Scusate e se dovessi inserire un’immagine invece che una label in detail View come posso fare?
    Grazie… 😀

  17. 18 Novembre 2010

    Cesare

    Articolo interessante e l’ho applicato ad una tableview con due viste ma capovolgendo la cosa-sono le viste che implementano una mutablearray comune e quindi i dati della tableview mapiccolo problema quando la tableview deve aggiornarsi perche la mutablearray passata a “singleton” e mutata, l’applicazione va in crash, applico il reloadData ma l’applicazione non accetta che si muti la mutableArray.
    Avete una soluzione
    Ciao a tutti

  18. 8 Settembre 2011

    milonet

    veramente un’ottimo modo per passare i dati da una classe ad un’altra.. stavo giusto impazzendo in questi giorni per capire come si faceva! ottimo 😀

  19. 15 Ottobre 2012

    Salvo

    grazie Andrea,
    funziona tutto, però ora con XCode 4.5 ottengo un warning per la memoria (Potential leak of an Object) in questo metodo:
    —

    + (Singleton *)sharedManager
    {
    @synchronized(self) {
    if (sharedClass == nil) {
    [[self alloc] init]; // assignment not done here
    }
    }
    return sharedClass;

    }

    —

    Come possiamo evitarlo?
    grazie, ciao
    salvo

  20. 16 Ottobre 2012

    Salvo

    ok,
    qui sembra funzionare (il warning scompare e non vedo per ora controindicazioni) cambiando in questo modo:
    + (Singleton *)sharedManager

    {
    @synchronized(self) {
    if (sharedClass == nil) {
    /// [[self alloc] init]; // assignment not done here
    // per evitare il warning "Potential leak of an Object"
    sharedClass = [[super allocWithZone:NULL] init];
    }
    }
    return sharedClass;
    }

    che ne pensate?

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