Domanda

Voglio creare programatically un dizionario che alimenta i dati al mio UITableView ma sto avendo un momento difficile con esso. Voglio creare un dizionario che assomiglia questo elenco delle proprietà (immagine) dare o prendere un paio di elementi.

Ho guardato "Guida Lista Proprietà di programmazione: Creazione di elenchi di proprietà a livello di programmazione " e mi si avvicinò con un piccolo campione di mio:

//keys

NSArray *Childs = [NSArray arrayWithObjects:@"testerbet", nil];
NSArray *Children = [NSArray arrayWithObjects:@"Children", nil];
NSArray *Keys = [NSArray arrayWithObjects:@"Rows", nil];
NSArray *Title = [NSArray arrayWithObjects:@"Title", nil];

//strings

NSString *Titles = @"mmm training";

//dictionary 

NSDictionary *item1 = [NSDictionary dictionaryWithObject:Childs, Titles forKey:Children , Title];
NSDictionary *item2 = [NSDictionary dictionaryWithObject:Childs, Titles forKey:Children , Title];
NSDictionary *item3 = [NSDictionary dictionaryWithObject:Childs, Titles forKey:Children , Title];
NSArray *Rows = [NSArray arrayWithObjects: item1, item2, item3, nil];
NSDictionary *Root = [NSDictionary dictionaryWithObject:Rows forKey:Keys];

// NSDictionary *tempDict = [[NSDictionary alloc] //initWithContentsOfFile:DataPath];
NSDictionary *tempDict = [[NSDictionary alloc] initWithDictionary: Root];

Sto cercando di utilizzare questi dati di gerarchia per il mio punto di vista della tabella.

Così mi chiedevo come posso è possibile creare l'elenco delle proprietà (dizionario) a livello di codice in modo che possa riempire con i miei array.

Sono ancora nuovo con lo sviluppo iPhone in modo da portare con me. ;)

È stato utile?

Soluzione

Questa è una situazione in cui "insegnare a un uomo a pescare" è un approccio di gran lunga più utile di "dare un uomo un pesce". Una volta compresi i principi di base e le API NSDictionary, diventa molto più facile per le imbarcazioni la propria soluzione personalizzata. Qui ci sono alcune osservazioni e punti di apprendimento:

  • Il metodo +dictionaryWithObject:forKey: viene usato per creare un NSDictionary con una singola coppia chiave-valore. Non accetterà argomenti separati da virgola dopo ogni due punti (:) nella chiamata al metodo, uno solo. Per creare un dizionario con più coppie chiave-valore, utilizzare uno dei 2 metodi correlati: +dictionaryWithObjects:forKeys: che accetta due oggetti NSArray contenenti i valori e le chiavi, o +dictionaryWithObjectsAndKeys: che alterna (oggetto, chiave, oggetto, chiave) con un argomento di terminazione nil.
  • Semplificare il codice di creazione. Non hai bisogno di un milione di variabili locali solo per creare la cosa. Utilizzare gli argomenti in linea in cui ha senso. Un modo per fare questo per costruire il dizionario in codice come un NSMutableDictionary , poi (se necessario) fare una copia immutabile di esso chiamando -copy su di esso. (Ricordate che un metodo di copia restituisce un nuovo oggetto che è necessario rilasciare per evitare perdite di memoria.) In questo modo non c'è bisogno di avere una variabile per ogni singolo valore in modo da poter fare una creazione "one shot" della struttura (s ) ad ogni livello.
  • Usa +arrayWithObject: per creare un NSArray con un singolo oggetto.
  • (suggerimenti di stile) Non usare mai una lettera maiuscola per iniziare il nome di una variabile, un metodo o una funzione. (Si noti che così mette in evidenza le variabili che portano-caps come nomi di classi.) Sarà sicuramente aiutare gli altri che leggono il codice da essere confuso circa il vostro intento dal vostro schema di denominazione.

Solo per darvi un assaggio di ciò che la creazione del dizionario nell'immagine collegata potrebbe essere simile nel codice ... (sto ignorando i vostri nomi variabile scelta e l'utilizzo di entrambi gli approcci diversi per completezza.)

NSDictionary *item1 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Screen J",[NSNumber numberWithInt:3],nil]
                                                  forKeys:[NSArray arrayWithObjects:@"Title",@"View",nil]];
NSDictionary *item2 = [NSDictionary dictionaryWithObjectsAndKeys:
                                        @"Screen I", @"Title", 
                                        [NSArray arrayWithObject:item1], @"Children", 
                                        nil];
...

Altri suggerimenti

Non sono sicuro di aver capito l'obiettivo fondamentale qui.

Sembra che in fase di esecuzione, si sta costruendo un dizionario profondo con molti nodi figli. Ma si sta costruendo tutto questo con il codice statico ... perché si può non semplicemente fare un plist (come quello che si aveva un'immagine di) e leggere che in un NSDictionary? Sia NSDictionary e NSArray hanno metodi che consentono di leggere semplicemente in un file e ottenere un intero compilato oggetto. Poi è il modo più facile da modificare e da capire. Questo metodo è dictionaryWithContentsOfFile.

Se tutti i dati sono veramente creato in fase di esecuzione prima che venga messo nel dizionario, allora sembra che si vorrebbe un ben diverso, ricorsivo, lo stile di codice piuttosto che gli esempi forniti piatti.

Infine, io personalmente piace il metodo dictionaryWithObjects:forKeys: in NSDictionary per la costruzione di un dizionario. Se devi fare le cose in questo modo preferisco di gran lunga il metodo dictionaryWithObjectsAndKeys: alternativo che fa la stessa cosa, ma mantiene i tasti con gli oggetti:

NSDictionary *item1 = [NSDictionary dictionaryWithObjectsAndKeys:
                       @"Screen J",
                       @"Title",
                       [NSNumber numberWithInt:3],
                       @"View"];
NSMutableDictionary *topLevel = [NSMutableDictionary dictionary];

NSMutableDictionary *item1 = [NSMutableDictionary dictionary];
NSString *item1title = [NSString stringWithString:@"Title 1"];
NSMutableDictionary *item1children = [NSMutableDictionary dictionary];

//  create children
NSString *item1child1 = [NSString stringWithString:@"item 1, child 1"];

NSMutableDictionary *item1child2 = [NSMutableDictionary dictionary];
NSString *item1child2title = [NSString stringWithString:@"Title 1-2"];
NSMutableDictionary *item1child2children = [NSMutableDictionary dictionary];

NSString *item1child2child1 = [NSString stringWithString:@"item 1, child 2, child 1"];
NSString *item1child2child2 = [NSString stringWithString:@"item 1, child 2, child 2"];

[item1child2 setObject:item1child2title forKey:@"Title"];
[item1child2children setObject:item1child2child1 forKey:@"item 1 child2 child 1"];
[item1child2children setObject:item1child2child2 forKey:@"item 1 child2 child 2"];

[item1child2 setObject:item1child2children forKey:@"children"];

//  add children to dictionary
[item1children setObject:item1child1 forKey:@"item1 child1"];
[item1children setObject:item1child2 forKey:@"item1 child2"];

//  add to item 1 dict
[item1 setObject:item1title forKey:@"Title"];
[item1 setObject:item1children forKey:@"children"];

NSMutableDictionary *item2 = [NSMutableDictionary dictionary];
NSString *item2title        = [NSString stringWithString:@"Title"];
NSMutableDictionary *item2children  = [NSMutableDictionary dictionary]; 

NSString *item2child1 = [NSString stringWithString:@"item 2, child 1"];
NSString *item2child2 = [NSString stringWithString:@"item 2, child 2"];
NSString *item2child3 = [NSString stringWithString:@"item 2, child 3"];

//  add children to dictionary
[item2children setObject:item2child1 forKey:@"item2 child1"];
[item2children setObject:item2child2 forKey:@"item2 child2"];
[item2children setObject:item2child3 forKey:@"item2 child3"];

//  add to item 2 dict
[item2 setObject:item2title forKey:@"Title"];
[item2 setObject:item2children forKey:@"children"];

[topLevel setObject:item1 forKey:@"Item 1"];
[topLevel setObject:item2 forKey:@"Item 2"];

prima di .. super! grazie .. Ho davvero apprezzato la spiegazione e frammento di codice. Dal momento che mi hai dato una buona spiegazione come spero che non mi dispiace chiedere a un paio di domande.

Per prima cosa, ho fatto come avete suggerito e questo è ciò che mi si avvicinò con: (Io ho usato la mia lista di proprietà originale anziché l'esempio questa volta quindi questo è dove la tabella di drill-down ottiene il suo (o ha la necessità di ottenere il suo) treestructure).

http://img509.imageshack.us/img509/7523/picture2lsg.png

NSDictionary *root = [NSMutableDictionary dictionary];
NSDictionary *item1 = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:@"VirtuaGym Online"] forKey:[NSArray arrayWithObjects:@"Title"]];
NSDictionary *item2 = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:@"Do the training"] forKey:[NSArray arrayWithObjects:@"Title"]];
NSDictionary *item3 = ... 

[root setObject:item1 forKey:@"Item 1"];
[root setObject:item2 forKey:@"Item 2"];

Abbiamo fatto anche qualche ricerca e ho cercato qualcosa di diverso con qualche altro ingresso ..

NSMutableArray *Rows = [NSMutableArray arrayWithCapacity: 1];

for (int i = 0; i < 4; ++i) {
  NSMutableArray *theChildren = [NSMutableArray arrayWithCapacity: 1];
  [theChildren addObject: [NSString stringWithFormat: @"tester %d", i]];
NSString *aTitle = [NSString stringWithFormat: @"Item %d", i];
  NSDictionary *anItem = [NSDictionary dictionaryWithObjectsAndKeys: aTitle, @"Title", theChildren, @"Children"];
  [Rows addObject: anItem];
}

NSDictionary *Root = [NSDictionary withObject: Rows andKey: @"Rows"];

Ho deciso di provare solo entrambi questi però si fa quello che voglio. Mi dà un errore di EXC_BAD_ACCESS.

Io vorrei sapere da quando ti ho visto utilizzare numero in snippet di codice, non potresti usare anche NSString dato che questo è ciò che il plist utilizza .. potrebbe essere del tutto di qui, naturalmente,

NSDictionary *item1 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Screen J",[NSNumber numberWithInt:3],nil]
                                                  forKeys:[NSArray arrayWithObjects:@"Title",@"View",nil]];

e il terzo una domanda riguarda il mio approccio possibile per la mia app. Ho un parser XML che salva alcune informazioni in diverse matrici. Voglio usare questa informazione per i miei UITableviews drill-down (infoFirstScreen [] infoSecondScreen [] infoThirdScreen []). Le informazioni fornite deve essere collegato come l'albero vi ho mostrato sopra. Questa è la ragione per cui ho voluto costruire il dizionario nel codice in modo da poter prendere informazioni dai miei array e inserirla qui. La mia domanda pensi che il mio approccio è corretto, sbagliato o c'è un modo più veloce?

ancora una volta davvero apprezzare la spiegazione;)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top