10

我想以编程方式创建一个向我的 UITableView 提供数据的字典,但我很难使用它。我想创建一个类似于此属性列表(图像)的字典,提供或获取几个项目。

我查看了“Property List Programming Guide: Creating Property Lists Programmatically”,并提出了自己的一个小样本:

//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 开发的新手,所以请耐心等待。;)

4

4 回答 4

25

在这种情况下,“授人以渔”比“授人以渔”更有帮助。一旦您了解了基本原理和 NSDictionary API,就可以更轻松地制作您自己的自定义解决方案。以下是一些观察和学习点:

  • 该方法+dictionaryWithObject:forKey:用于创建具有单个键值对的 NSDictionary。它不会在方法调用中的每个冒号 (:) 之后接受逗号分隔的参数,只接受一个。要创建具有多个键值对的字典,请使用以下两种相关方法之一:+dictionaryWithObjects:forKeys:它接受两个包含值和键的 NSArray 对象,或者+dictionaryWithObjectsAndKeys:使用终止nil参数交替 (object, key, object, key)。
  • 简化创建代码。您不需要一百万个局部变量来创建事物。在有意义的地方使用内联参数。一种方法是在代码中将您的字典构建为NSMutableDictionary,然后(如有必要)通过调用它来制作它的不可变副本-copy。(请记住,复制方法会返回一个新对象,您必须释放该对象以避免内存泄漏。)这样您就不必为每个单个值都有一个变量,因此您可以“一次性”创建结构(s ) 在每个级别。
  • 用于+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];
...
于 2009-07-14T15:36:42.950 回答
2

我不确定我是否理解这里的基本目标。

似乎在运行时,您正在构建一个包含许多子节点的深度字典。但是您正在使用静态代码构建这一切......为什么您不能简单地制作一个 plist(就像您拥有图像的那个)并将其读入 NSDictionary?NSDictionary 和 NSArray 都有方法可以让你简单地读入一个文件并得到一个完整的对象。然后它更容易编辑和理解。那个方法是dictionaryWithContentsOfFile

如果所有数据在放入字典之前真正在运行时创建,那么您似乎需要一种非常不同的、递归的代码风格,而不是给出的平面示例。

最后,我个人不喜欢dictionaryWithObjects:forKeys:NSDictionary 中构建字典的方法。如果您必须以这种方式做事,我非常喜欢替代方法dictionaryWithObjectsAndKeys:,它做同样的事情但将键与对象保持一致:

NSDictionary *item1 = [NSDictionary dictionaryWithObjectsAndKeys:
                       @"Screen J",
                       @"Title",
                       [NSNumber numberWithInt:3],
                       @"View"];
于 2009-07-15T05:51:16.227 回答
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"];
于 2009-07-14T12:57:37.367 回答
0

第一个..超级!谢谢..我非常感谢解释和代码片段。既然你给了我这么好的解释,我希望你不介意我再问几个问题。

首先,我按照你的建议做了,这就是我想出的:(这次我使用了我的原始属性列表而不是示例,所以这是向下钻取表获取他的(或需要获取他的)树结构的地方)。

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 解析器,它将某些信息保存在不同的数组中。我想将此信息用于我的向下钻取 UITableviews (infoFirstScreen[] infoSecondScreen[] infoThirdScreen[])。提供的信息必须像我在上面展示的树一样连接起来。这就是我想在代码中构建字典的原因,这样我就可以从我的数组中获取信息并将其插入到这里。我的问题你认为我的方法是正确的,错误的还是有更快的方法?

再次非常感谢您的解释;)

于 2009-07-15T05:33:09.367 回答