将不相互引用的对象添加到 NSMutableArray
Add objects to NSMutableArray that don't reference each other
第一个问题:
基本上我试图通过使用方法 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 (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 (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 (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];
感谢所有帮助过的人。
我不能给你答案,没有提供足够的信息来做到这一点,但也许我可以帮助你自己弄清楚。你写:
Im aware this is because an array simply retains a memory address, hence when the same object simply with a different type "obType" is added all of those values change.
这不是您的代码中发生的情况,尽管在某些情况下数组中的内容可能 看起来 发生变化 - 这就是您可能看到的情况。该行:
NSMutableDictionary *itemToAdd = [[NSMutableDictionary alloc]init];
生成一个新的、前所未见的可变字典。您可以通过添加以下内容来记录此对象的地址(实际上是身份(1)):
NSLog(@"Created itemToAdd: %p", itemToAdd);
在上面一行之后。 %p
格式会产生新创建的对象的地址,每个对象都有一个唯一的地址。当您到达该行时:
[items addObject:itemToAdd];
新词典被添加到 items
引用的 数组中 - 这 非常重要 。任何变量,比如items
和itemToAdd
,引用一个对象,它是而不是对象本身。因此,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
格式或添加演员表。
第一个问题: 基本上我试图通过使用方法 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 (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 (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 (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];
感谢所有帮助过的人。
我不能给你答案,没有提供足够的信息来做到这一点,但也许我可以帮助你自己弄清楚。你写:
Im aware this is because an array simply retains a memory address, hence when the same object simply with a different type "obType" is added all of those values change.
这不是您的代码中发生的情况,尽管在某些情况下数组中的内容可能 看起来 发生变化 - 这就是您可能看到的情况。该行:
NSMutableDictionary *itemToAdd = [[NSMutableDictionary alloc]init];
生成一个新的、前所未见的可变字典。您可以通过添加以下内容来记录此对象的地址(实际上是身份(1)):
NSLog(@"Created itemToAdd: %p", itemToAdd);
在上面一行之后。 %p
格式会产生新创建的对象的地址,每个对象都有一个唯一的地址。当您到达该行时:
[items addObject:itemToAdd];
新词典被添加到 items
引用的 数组中 - 这 非常重要 。任何变量,比如items
和itemToAdd
,引用一个对象,它是而不是对象本身。因此,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
格式或添加演员表。