2009-07-14 12 views
10

Chcę programowo utworzyć słownik, który przesyła dane do mojego UITableView, ale mam z tym problemy. Chcę utworzyć słownik przypominający this property list (image) podać lub wziąć kilka przedmiotów.Utwórz programowo listę właściwości słownika

Szukałem na "Property List Programming Guide: Creating Property Lists Programmatically" i wpadłem na małej próbce mój własny:

//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]; 

Staram się wykorzystywać te dane o hierarchię dla moich poglądów tabeli.

Tak więc zastanawiałem się, w jaki sposób mogę programowo utworzyć moją listę właściwości (słownik), aby móc wypełnić ją własnymi tablicami.

Nadal jestem nowy w rozwoju iPhone'a, więc trzymaj się mnie. ;)

Odpowiedz

24

Jest to sytuacja, w której "ucz się człowieka łowić" jest znacznie bardziej pomocnym podejściem niż "daj człowiekowi rybę". Gdy zrozumiesz podstawowe zasady i interfejs API NSDictionary, znacznie łatwiej będzie stworzyć własne niestandardowe rozwiązanie. Oto kilka obserwacji i punktów nauki:

  • Metoda +dictionaryWithObject:forKey: służy do tworzenia NSDictionary z jedną parą klucz-wartość. Nie będzie akceptował argumentów oddzielonych przecinkami po każdym dwukropku (:) w wywołaniu metody, tylko jeden. Aby utworzyć słownik z wieloma parami klucz-wartość, użyj jednej z 2 powiązanych metod: +dictionaryWithObjects:forKeys:, która akceptuje dwa obiekty NSArray zawierające wartości i klucze, lub +dictionaryWithObjectsAndKeys:, które zmieniają się (obiekt, klucz, obiekt, klucz) z kończącym argumentem nil.
  • Uprość kod tworzenia. Nie potrzebujesz miliona zmiennych lokalnych tylko po to, by coś stworzyć. Używaj argumentów wstawianych tam, gdzie ma to sens. Jednym ze sposobów na to jest zbudowanie słownika w kodzie jako , a następnie (jeśli to konieczne) utworzenie niezmiennej kopii przez wywołanie na nim -copy. (Pamiętaj, że metoda kopiowania zwraca nowy obiekt, który musisz zwolnić, aby uniknąć przecieków pamięci.) W ten sposób nie musisz mieć zmiennej dla każdej pojedynczej wartości, dzięki czemu możesz wykonać "jednorazowe" tworzenie struktury (s) na każdym poziomie.
  • Użyj obiektu +arrayWithObject: do utworzenia obiektu NSArray z pojedynczym obiektem.
  • (Sugestie dotyczące stylu) Nigdy nie należy używać dużej litery, aby rozpocząć nazwę zmiennej, metody lub funkcji. (Zwróć uwagę, że SO uwydatnia zmienne wiodących limitów, takie jak nazwy klas.) Z pewnością pomoże to osobom, które odczytują twój kod, z powodu twojego zamiaru, przez swój schemat nazewnictwa.

Wystarczy dać wam smak co tworzeniu słownika w połączonym obrazie może wyglądać w kodzie ... (jestem ignorując preferowane nazwy zmiennych i obiema różne podejścia do kompletności.)

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]; 
... 
0
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"]; 
+0

dzięki! ... Sprawdzę to i spróbuję się z nim trochę postarać, jeśli dobrze zrozumię te słowniczki;) Zauważyłem też, że nie korzystałeś z żadnych tablic (widziałem dzieci na przykład w łączu do zdjęć i przykładowa aplikacja), mam nadzieję, że nadal działa;) nawet jeśli nie masz mojej wdzięczności. again thnx .. –

0

pierwsza z .. super! dzięki ... Naprawdę doceniam wyjaśnienie i fragment kodu. Ponieważ dałeś mi takie dobre wyjaśnienie, mam nadzieję, że nie masz nic przeciwko, że zadam ci jeszcze kilka pytań.

Po pierwsze, zrobiłem to, co zasugerowałeś i to właśnie wymyśliłem: (Użyłem mojej oryginalnej listy własności zamiast przykładu tym razem, więc to jest miejsce, w którym stół odwiertowy dostaje jego (lub potrzebuje dostać jego) 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"]; 

zrobił także rozeznanie i próbowałem coś innego z innego wejścia ..

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"]; 

postanowiłem po prostu przetestować oba te jednak robi to co chcę. Daje mi błąd EXC_BAD_ACCESS.

Zastanawiałem się też, odkąd zobaczyłem cię przy użyciu numeru w fragmencie kodu, nie może też użyć NSString ponieważ to właśnie wykorzystuje plist .. może być całkowicie stąd oczywiście

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

i trzeci pytanie dotyczy mojego możliwego podejścia do mojej aplikacji. Mam parser xml, który zapisuje pewne informacje w różnych tablicach. Chcę użyć tych informacji do mojego wyszukiwania w dół UITableviews (infoFirstScreen [] infoSecondScreen [] infoThirdScreen []). Podane informacje muszą być połączone tak jak drzewo, które pokazałem powyżej. To jest powód, dla którego chciałem zbudować słownik w kodzie, abym mógł pobrać informacje z moich tablic i wstawić je tutaj. Moim zdaniem, czy moje podejście jest poprawne, błędne, czy istnieje szybszy sposób?

ponownie naprawdę docenić wyjaśnienia;)

+0

Jeśli chcesz zadać osobne pytanie, lepiej zamieścić nowe pytanie, aby uzyskać widoczność i odpowiedzi. –

2

nie jestem pewien, czy rozumiem podstawowy cel tutaj.

Wygląda na to, że w czasie wykonywania konstruujesz głęboki słownik z wieloma węzłami potomnymi. Ale konstruujesz to wszystko za pomocą statycznego kodu ... dlaczego nie możesz po prostu zrobić plist (jak ten, którego miałeś obraz) i przeczytać to w NSDictionary? Zarówno NSDictionary, jak i NSArray mają metody, które pozwalają ci po prostu przeczytać w pliku i uzyskać cały wypełniony obiekt. Łatwiej jest edytować i rozumieć WAY. Ta metoda to dictionaryWithContentsOfFile.

Jeśli wszystkie dane są rzeczywiście tworzone w środowisku wykonawczym przed umieszczeniem w słowniku, wydaje się, że chciałbyś otrzymać zupełnie inny, rekursywny styl kodu niż podane przykłady płaskie.

Wreszcie, osobiście nie lubię metody dictionaryWithObjects:forKeys: w NSDictionary do budowania słownika. Jeśli musisz robić rzeczy w ten sposób, bardzo wolę alternatywną metodę, która polega na tym, że zachowuje się tak samo, ale trzyma klucze z przedmiotami:

NSDictionary *item1 = [NSDictionary dictionaryWithObjectsAndKeys: 
         @"Screen J", 
         @"Title", 
         [NSNumber numberWithInt:3], 
         @"View"]; 
+1

Chciałem sprawdzić, czy udało mi się go usunąć, aby tak powiedzieć, żebym mógł później spróbować uczynić go bardziej rekursywnym i dynamicznym, na przykład trochę takim, jak ten for (int i = 0; i < 4; ++i) { NSMutableArray *theChildren = [NSMutableArray arrayWithCapacity: 1]; [theChildren addObject: [NSString stringWithFormat: @"tester %d", i]]; NSString *aTitle = [NSString Możesz zobaczyć "pełny" kod poniżej. Rzeczywiście moim celem jest bardziej dynamiczny charakter. Próbuję przynajmniej uruchomić słownik, aby móc zacząć tworzyć tę dynamikę. Last but not least Thnx za opinie –

Powiązane problemy