6

Con la maturazione del codebase sto iniziando a non gradire lo schema dei dizionari di passaggio come modo per impacchettare le informazioni per il passaggio dei messaggi o, peggio ancora, per gli argomenti delle funzioni. Richiede che la funzione di invio e ricezione abbiano entrambi un'API non documentata di stringhe letterali.Schema migliore del passaggio di NSDictionaries come parametri?

..in some function.. 
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: 
         thisObject, @"thisKey", 
         thatObject, @"thatKey", 
         nil]; 

[[NSNotificationCenter defaultCenter] postNotificationName:@"MY_NOTIFICATION" object:nil userInfo:info]; 
.... 

e poi in chi ascolta 's someClass

- (void)someClassListener:(NSNotification *)notification { 
    NSDictionary *info = [notification userInfo]; 

    ThisObject *ob1 = [info objectForKey:@"thisKey"]; 
    ThatObject *ob2 = [info objectForKey:@"thatKey"]; 
} 

Bisogna ricordare che thisKey e thatKey sono le chiavi di tipo ThisObject e ThatObject per tale notifica, sicuro che si potrebbe creare alcune costanti in qualche luogo per coloro le chiavi ma questo non risolve il problema.

E diciamo che hai una funzione che richiede 15 argomenti, non hai intenzione di fare una funzione con 15 parametri, sarebbe molto più facile (anche se meno leggibile) passare semplicemente un dizionario ma ora hai il lo stesso problema di cui sopra.

Ho giocato con la creazione di "Classi di messaggi" cancellate nei file di intestazione di questa classe (ovvero due interfacce in un'intestazione) e la Classe messaggio era solo un elenco di oggetti definiti e inviati al metodo che crea un più forte contratto ma questo sembra sbagliato.

Sarebbe bello se potessi fare qualcosa di simile typeDef un oggetto parametro nell'intestazione, ma che non supporta NSObject 's solo le cose come int o float ecc

In sostanza sto cercando di creare un contratto più forte tra il mittente del messaggio e il destinatario del messaggio, siano quelle funzioni o notifiche.

risposta

4

È possibile definire le costanti per le chiavi. Ad esempio, consultare i documenti per UIKeyboardDidShowNotification per un esempio. C'è un collegamento a tutti i tasti che possono essere utilizzati per ottenere informazioni sulla notifica.

Un approccio migliore sarebbe incapsulare i dati in una classe anziché in un dizionario. Crea una classe semplice con proprietà. Questo sarà molto più auto-documentante di un dizionario. È possibile visualizzare i nomi delle proprietà e i tipi di proprietà nel file .h.

Se si riscontrano metodi che richiedono 15 argomenti, è necessario fare un passo indietro e incapsulare tali argomenti in una classe appropriata. Forse il metodo si riduce correttamente a un paio di argomenti e una classe o qualcosa di simile.

+0

Io dico che le costanti per le chiavi non sono una buona soluzione perché devi ancora cercare la chiave e non sta creando un contratto forte per quale sarà il valore (oggetto), più come un suggerimento. Incapsulare i dati in una classe era una direzione che stavo investigando, ma mi sembra complicato creare una classe per ogni messaggio che voglio passare, che siano 2 argomenti 10, non sei d'accordo? – Shizam

+0

@Shizam, se quei messaggi verrebbero inseriti in dizionari diversi, probabilmente avresti bisogno di più di una classe. Ma, se stai parlando di messaggi che a volte passano due chiavi da un dizionario, e talvolta da 10, allora sarebbe ancora solo un oggetto di classe. – rdelmar

+0

@rdelmar In tutto il nostro programma abbiamo probabilmente 10-15 notifiche univoche, ognuna di quelle notifiche avrebbe bisogno della propria classe per definire le sue proprietà per il messaggio, ecc. – Shizam

2

Quello che si desidera è un oggetto parametro , un piccolo oggetto che racchiude un gruppo di campi per comunicazioni utili con altre classi. Internamente, l'oggetto parametro potrebbe contenere un dizionario o semplicemente un insieme di campi designati.

Assegna all'oggetto parametro una semplice API che consente a entrambe le classi di impostare e ottenere i campi specifici che si utilizzano - setThisKey: e getThisKey. Questo, in sostanza, documenta l'API tra i metodi e le classi.

Successivamente, cercare le opportunità per spostare le funzionalità nell'oggetto parametro.Per esempio, se avete qualcosa di simile:

param.fieldSize=[self.data size]; 
param.fieldColor=[self.data color]; 
param.flavor=[self.data lookUpTheRecipe] 

Si potrebbe racchiudere tutto questo con

[param withField: self.data]; 

Con il lavoro, spesso è possibile rendere l'oggetto parametro di fare un sacco di lavoro utile; questo può rompere i metodi lunghi e aiutare le grandi classi a perdere le responsabilità in eccesso.

+0

Lo dico come una soluzione che stavo guardando, il problema che vedo è dover creare un oggetto parametro per ogni messaggio, sembra complicato. Inoltre sembra che lo spot per mettere quell'oggetto sia nell'intestazione della classe che "possiede" il messaggio in modo tale che tu abbia due interfacce in un'intestazione che sembra essere disapprovata. – Shizam

+0

Spesso è possibile condividere un oggetto parametro tra diversi metodi correlati. –

+1

Non vedo obiezioni all'aggiunta di interfacce agli oggetti helper nell'intestazione di una classe. Ma il tuo obiettivo con un oggetto parametro è aggiungere un sacco di comportamento utile a quell'oggetto, non solo per racchiudere alcuni dati. Quindi, alla fine, l'oggetto parametro potrebbe meritare il proprio posto nel mondo. Classi come NSURL iniziano così. –

0

All'inizio, avere 15 argomenti non è buono e in tal caso si dovrebbe pensare a non fare tali richiamate o cercare di ridurre il numero.


E il mittente della notifica? Ad esempio l'oggetto Task è terminato e invia una notifica. Il destinatario utilizza il mittente per accedere a sender.result, sender.error, sender.anything.


Se volete più forte contatto tra quegli oggetti (mittente/destinatario) Forse si dovrebbe utilizzare un altro mezzo di comunicazione, invece di NSNotifications.

Alcune alternative:

  • delegato (o qualche altro tipo di metodo di chiamata diretta)
  • blocchi
  • bersaglio + azione

Tutti loro possono essere usati come a-molti richiamate memorizzandole in un array e non usano NSDictionaries per il passaggio di valori.

+0

Utilizziamo anche delegati e blocchi, stavo usando NSNotifications come esempio in cui è facile vedere il problema. Ho ancora questo problema con i blocchi ecc, ma sto iniziando a pensare che la creazione di oggetti parametro per contenere i parametri sia praticamente l'unico modo per farlo. – Shizam

Problemi correlati