【问题标题】:Add objects to NSMutableArray that don't reference each other将不相互引用的对象添加到 NSMutableArray
【发布时间】:2015-07-18 02:24:18
【问题描述】:

第一个问题: 基本上我试图通过使用方法 addItem 将 NSMutableDictionary 对象添加到 NSMutableArray。

-(void)addItem:(id)ObID name:(id)ObName description:(id)ObDesc menuName:(id)ObmName menuID:(id)ObmID mid:(id)Obmid pod:(id)pod type:(id)obType price:(id)price
{
    NSMutableDictionary *itemToAdd = [[NSMutableDictionary alloc]init];
    [itemToAdd setValue:ObID forKey:@"id"];
    [itemToAdd setValue:ObName forKey:@"name"];
    [itemToAdd setValue:ObDesc forKey:@"description"];
    [itemToAdd setValue:ObmName forKey:@"mname"];
    [itemToAdd setValue:ObmID forKey:@"menu_id"];
    [itemToAdd setValue:Obmid forKey:@"mid"];
    [itemToAdd setValue:pod forKey:@"POD"];
    [itemToAdd setValue:obType forKey:@"Type"];
    [itemToAdd setValue:price forKey:@"Price"];
    [itemToAdd setValue:@"1" forKey:@"Amount"];

    [items addObject:itemToAdd];
}

但是,当稍后再次调用此方法时,添加到的下一个对象将覆盖具有相同键的对象的值。我知道这是因为数组只保留了一个内存地址,因此当添加相同的对象只是具有不同类型的“obType”时,所有这些值都会改变。

如何在不相互引用的情况下将对象添加到 NSMutableArray?

例子:

添加一个对象后的输出:

        {
    Amount = 1;
    POD = BOTH;
    Type =         {
        0 = Vegetarian;
        1 = Aussie;
    };
    description = "Online Special Only - Two Large Pizza's $25 (No half halves or extra toppings!) Enjoy!";
    id = 7596;
    "menu_id" = 112;
    mid = 112;
    mname = "Deal";
    name = "Hungry? Two Large Pizzas!";
}

)

添加另一个具有相同 ID 但类型不同的对象后的输出:

    {
    Amount = 1;
    POD = BOTH;
    Type =         {
        0 = "Plain";
        1 = Aussie;
    };
    description = "Online Special Only - Two Large Pizza's $25 (No half halves or extra toppings!) Enjoy!";
    id = 7596;
    "menu_id" = 112;
    mid = 112;
    mname = "Deal";
    name = "Two Large Pizzas!";
},
    {
    Amount = 1;
    POD = BOTH;
    Type =         {
        0 = "Plain";
        1 = Aussie;
    };
    description = "Online Special Only - Two Large Pizza's $25 (No half halves or extra toppings!) Enjoy!";
    id = 7555;
    "menu_id" = 112;
    mid = 112;
    mname = "Deal";
    name = Two Large Pizzas!";
}

)

可以看出,两种对象类型都发生了变化。

好的,所以我解决了这个问题,但不是 100% 确定原因。 我将类型对象作为 NSMutableDictionary 传入,如果一个项目有 2 个变体,则字典中的一个对象的键为 0,而当像这样传入时,另一个对象的键为 1,它们会相互覆盖。 仅将值作为 NSArray 传递可以解决此问题。

通过传入完成:

NSArray * values = [selectedItemOptions allValues];

感谢所有帮助过的人。

【问题讨论】:

  • 我建议在此方法开始时记录项目的计数值,以实际确认前一个对象仍然存在。此外,查看项目的声明和初始化方式和位置可能很有用。

标签: ios objective-c nsmutablearray nsdictionary


【解决方案1】:

我不能给你答案,没有提供足够的信息来做到这一点,但也许我可以帮助你自己弄清楚。你写:

我知道这是因为数组只是保留了一个内存地址,因此当添加了具有不同类型“obType”的同一个对象时,所有这些值都会发生变化。

这不是您的代码中发生的情况,尽管在某些情况下,数组中的内容可能似乎发生变化 - 这就是您可能看到的情况。行:

NSMutableDictionary *itemToAdd = [[NSMutableDictionary alloc]init];

生成一个新的、前所未见的可变字典。您可以通过添加以下内容来记录此对象的地址(实际上是身份(1)):

NSLog(@"Created itemToAdd: %p", itemToAdd);

在上述行之后。 %p 格式会产生新创建对象的地址,每个对象都有一个唯一的地址。当你到达线路时:

[items addObject:itemToAdd];

新字典被添加到items 引用的数组 - 这非常重要。任何变量,例如itemsitemToAdd引用一个对象,它不是对象本身。因此items 引用的数组可能会在对addItem: 的调用之间发生变化。你应该检查这个,你可以通过添加(2)来做到这一点:

NSLog(@"addItem called, items = %p containing %ld element", items, items.count);
for(id someThing in items)
   NSLog(@"    element: %p", someThing);

到你的方法的开始。这将首先告诉您items 当前引用的数组的地址以及该数组包含多少项。然后for 循环将输出数组中每个元素的地址(如果有的话)。

进一步注意addObject: 将始终向数组中添加一个项目,相同的项目是否已经在数组中并不重要 - 将它添加两次并且数组似乎有两个元素,这两个元素都引用相同的项目。当上面的代码显示计数时,它应该会增加,除非您从某个数组中删除元素。

添加这些语句并查看结果。在可能产生您报告的结果的可能性中:

  • items 引用的数组正在发生变化
  • 正在删除您添加的字典

HTH


(1) 地址可以重复使用,在对象不再需要并被 ARC 销毁后,它的内存可以重新用于新对象。所以地址并不严格标识一个唯一的对象,你只需要注意这一点

(2) 我这里假设是 64 位的,如果不是你需要更改 %ld 格式或添加演员表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2020-12-10
    • 2014-12-20
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    相关资源
    最近更新 更多