2015-07-18 14 views
0

Первый вопрос: В основном я пытаюсь добавить объекты NSMutableDictionary в NSMutableArray с помощью метода addItem.Добавить объекты в 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]; 

Спасибо всем, кто помог.

+0

Я предлагаю регистрировать значение счета элементов в начале этого метода, чтобы фактически подтвердить, что предыдущий объект все еще существует. Также может быть полезно посмотреть, как и где элементы объявлены и инициализированы. – Bamsworld

ответ

0

Я не могу дать вам ответ, информации для этого недостаточно, но, возможно, я могу помочь вам разобраться в этом. Вы пишете:

Im известно, что это потому, что массив просто сохраняет адрес памяти, следовательно, при добавлении одного и того же объекта с другим типом «obType» все эти значения изменяются.

Это не то, что происходит в вашем коде, хотя бывают ситуации, когда то, что в массиве может появляются изменения - и это то, что вы, вероятно, видеть. Линия:

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 меняется
  • Словарь добавления удаляется
  • Etc.

HTH


(1) Адреса могут повторно использоваться после того, как объект больше не требуется. nd, уничтоженный ARC, его память может быть повторно использована для нового объекта. Таким образом, адрес строго не идентифицирует уникальный объект, вам просто нужно знать об этом

(2) Я предполагаю здесь 64-битный код, если нет, вам нужно изменить формат %ld или добавить состав.

Смежные вопросы