【问题标题】:Create a dictionary property list programmatically以编程方式创建字典属性列表
【发布时间】:2009-07-14 12:26:25
【问题描述】:

我想以编程方式创建一个向我的 UITableView 提供数据的字典,但我很难使用它。我想创建一个类似于this property list (image) 的字典,给予或接受几个项目。

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

【问题讨论】:

    标签: iphone objective-c nsdictionary


    【解决方案1】:

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

    • +dictionaryWithObject:forKey: 方法用于创建具有单个键值对的 NSDictionary。它不会在方法调用中的每个冒号 (:) 之后接受逗号分隔的参数,只接受一个。要创建具有多个键值对的字典,请使用以下两种相关方法之一:+dictionaryWithObjects:forKeys: 接受两个包含值和键的 NSArray 对象,或 +dictionaryWithObjectsAndKeys: 将 (object, key, object, key) 与终止 @ 987654330@ 论据。
    • 简化创建代码。您不需要一百万个局部变量来创建事物。在有意义的地方使用内联参数。一种方法是在代码中将您的字典构建为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];
    ...
    

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

      • 我想测试一下我是否能够把它拉下来,这样我以后就可以尝试使它确实更具递归性和动态性,例如有点像这样 for (int i = 0; i 你可以在下面看到“完整”的代码。事实上,我的实际目标是更具动态性。我正在努力至少让字典工作,这样我就可以开始制作动态了。最后但并非最不重要的一点是感谢您的反馈
      【解决方案3】:
      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"];
      

      【讨论】:

      • 谢谢你! ...我要检查一下并尝试玩一下,看看我是否正确理解了这些字典内容;)我还注意到您没有使用任何数组(例如,我在图片链接中看到了孩子和示例应用程序),我希望它仍然有效;)即使你没有我的感激之情。再次thnx ..
      【解决方案4】:

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

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

      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 错误。

      我也想知道,因为我看到你在你的代码 sn-p 中使用数字,你不能也使用 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[])。 提供的信息必须像我在上面展示的树一样连接起来。 这就是我想在代码中构建字典的原因,这样我就可以从我的数组中获取信息并将其插入到这里。 我的问题你认为我的方法是正确的,错误的还是有更快的方法?

      再次感谢您的解释;)

      【讨论】:

      • 如果您想提出一个单独的问题,最好发布一个新问题,以便获得可见性和答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多