将对象添加到不相互引用的NSMutableArray

时间:2015-07-18 02:24:19

标签: ios objective-c nsmutablearray nsdictionary

第一个问题: 基本上我是尝试使用方法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的键,而另一个对象在传入时会相互覆盖。 仅将值作为NSArray传递就可以解决这个问题。

完成传递:

NSArray * values = [selectedItemOptions allValues];

感谢所有帮助过的人。

1 个答案:

答案 0 :(得分:0)

我无法给你答案,没有提供足够的信息来做到这一点,但也许我可以帮你解决一下。你写道:

  

我知道这是因为一个数组只是保留了一个内存地址,因此当同一个对象只是一个不同的类型" 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格式或添加演员。