Программное создание списка свойств словаря

Я хочу программно создать словарь, который передает данные в мой UITableView, но у меня с этим проблемы. Я хочу создать словарь, похожий на этот список свойств (изображение) плюс-минус несколько элементов.

Я просмотрел "Руководство по программированию списка свойств: создание списков свойств" Программно", и я придумал небольшой собственный образец:

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

Я пытаюсь использовать эти данные иерархии для своих табличных представлений.

Поэтому мне было интересно, как я могу создать свой список свойств (словарь) программно, чтобы я мог заполнить его своими собственными массивами.

Я все еще новичок в разработке iPhone, так что терпите меня. ;)


person Community    schedule 14.07.2009    source источник


Ответы (4)


Это ситуация, когда «научить человека ловить рыбу» гораздо полезнее, чем «дать человеку рыбу». Как только вы поймете основные принципы и API NSDictionary, станет намного проще создавать собственное решение. Вот несколько наблюдений и уроков:

  • Метод +dictionaryWithObject:forKey: используется для создания NSDictionary с одной парой ключ-значение. Он не будет принимать аргументы, разделенные запятыми, после каждого двоеточия (:) в вызове метода, только один. Чтобы создать словарь с несколькими парами ключ-значение, используйте один из двух связанных методов: +dictionaryWithObjects:forKeys:, который принимает два объекта NSArray, содержащие значения и ключи, или +dictionaryWithObjectsAndKeys: который чередуется (объект, ключ, объект, ключ) с завершающим аргументом nil.
  • Упростите код создания. Вам не нужен миллион локальных переменных только для того, чтобы создать вещь. Используйте встроенные аргументы там, где это имеет смысл. Один из способов сделать это — создать свой словарь в коде как NSMutableDictionary., затем (при необходимости) сделайте его неизменяемую копию, вызвав -copy на нем. (Помните, что метод копирования возвращает новый объект, который вы должны освободить, чтобы избежать утечек памяти.) Таким образом, вам не нужно иметь переменную для каждого отдельного значения, поэтому вы можете создать структуру (структуры) «одним выстрелом». ) на каждом уровне.
  • Используйте +arrayWithObject: для создания NSArray с одним объектом.
  • (Предложения по стилю) Никогда не используйте заглавную букву в начале имени переменной, метода или функции. (Обратите внимание, что SO выделяет переменные с начальными буквами, такие как имена классов.) Это, безусловно, поможет другим, кто читает ваш код, не запутаться в ваших намерениях вашей схемой именования.

Просто чтобы дать вам представление о том, как создание словаря в связанном изображении может выглядеть в коде... (я игнорирую выбранные вами имена переменных и использую оба разных подхода для полноты.)

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];
...
person Quinn Taylor    schedule 14.07.2009

Я не уверен, что понимаю основную цель здесь.

Похоже, что во время выполнения вы создаете глубокий словарь со многими дочерними узлами. Но вы строите все это с помощью статического кода... почему вы не можете просто создать plist (например, тот, изображение которого у вас есть) и прочитать его в NSDictionary? И в NSDictionary, и в NSArray есть методы, позволяющие просто прочитать файл и получить полностью заполненный объект. Тогда это НАМНОГО легче редактировать и понимать. Этот метод dictionaryWithContentsOfFile.

Если все данные действительно создаются во время выполнения, прежде чем они будут помещены в словарь, то кажется, что вам нужен совершенно другой, рекурсивный стиль кода, а не приведенные простые примеры.

Наконец, лично мне не нравится метод dictionaryWithObjects:forKeys: в NSDictionary для создания словаря. Если вам нужно делать что-то таким образом, я предпочитаю альтернативный метод dictionaryWithObjectsAndKeys:, который делает то же самое, но сохраняет ключи с объектами:

NSDictionary *item1 = [NSDictionary dictionaryWithObjectsAndKeys:
                       @"Screen J",
                       @"Title",
                       [NSNumber numberWithInt:3],
                       @"View"];
person Kendall Helmstetter Gelner    schedule 15.07.2009
comment
Я хотел проверить, смогу ли я, так сказать, справиться с этим, чтобы позже попытаться сделать его действительно более рекурсивным и динамичным, например, немного похожим на этот ‹code›for (int i = 0; i ‹ 4; + +i) { NSMutableArray *theChildren = [массив NSMutableArrayWithCapacity: 1]; [theChildren addObject: [NSString stringWithFormat: @tester %d, i]]; NSString *aTitle = [NSString ‹/code› Вы можете увидеть полный код ниже. Действительно, моя настоящая цель носит более динамичный характер. Я пытаюсь, по крайней мере, заставить словарь работать, чтобы я мог начать делать это динамичным. И последнее, но не менее важное спасибо за ваш отзыв - person ; 15.07.2009

первый из .. супер! спасибо .. Я очень ценю объяснение и фрагмент кода. Поскольку вы дали мне такое хорошее объяснение, надеюсь, вы не возражаете, если я задам еще пару вопросов.

Во-первых, я сделал, как вы предложили, и вот что у меня получилось: (на этот раз я использовал свой исходный список свойств вместо примера, так что именно здесь таблица детализации получает свою (или должна получить свою) древовидную структуру).

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

Также провел некоторые исследования и попробовал что-то еще с некоторыми другими входными данными.

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

Я решил просто протестировать оба из них, однако он делает то, что я хочу. Выдает ошибку EXC_BAD_ACCESS.

Мне также было интересно, так как я видел, как вы используете число в своем фрагменте кода, не могли бы вы также использовать NSString, так как это то, что использует plist.. может быть здесь, конечно

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

и третий вопрос о моем возможном подходе к моему приложению. У меня есть парсер xml, который сохраняет определенную информацию в разных массивах. Я хочу использовать эту информацию для своих расширенных представлений UITableview (infoFirstScreen[] infoSecondScreen[] infoThirdScreen[]). Предоставленная информация должна быть связана, как дерево, которое я показал вам выше. Именно по этой причине я хотел создать словарь в коде, чтобы я мог взять информацию из своих массивов и вставить ее сюда. Мой вопрос, как вы думаете, мой подход правильный, неправильный или есть более быстрый способ?

еще раз очень ценю объяснение;)

person Community    schedule 15.07.2009
comment
Если вы пытаетесь задать отдельный вопрос, было бы лучше опубликовать новый вопрос, чтобы он был виден и получил ответы. - person Quinn Taylor; 11.05.2010

person    schedule
comment
Спасибо чувак! ... Я собираюсь проверить это и попытаться немного поиграть с ним, чтобы посмотреть, правильно ли я понимаю эти словарные штучки;) Я также заметил, что вы не использовали никаких массивов (например, я видел детей в ссылке на картинку и образец приложения) , я надеюсь, что он все еще работает ;) даже если это не так, примите мою благодарность. еще раз спс.. - person ; 14.07.2009