2011-12-18 2 views
3

С помощью следующего кода оба элемента в массиве одинаковы (последний элемент). Что я делаю неправильно, что заставляет этот массив перезаписывать значения? Я пытаюсь использовать 1 объект, поэтому мне не нужно создавать экземпляры X-объектов.Добавление нескольких NSObjects в NSMutableArray

self.myArray = [[NSMutableArray alloc] init]; 

MyObjClass *obj = [[MyObjClass alloc] init]; 
obj.firstName = @"First Name"; 
obj.lastName = @"Last Name"; 
obj.created = @"Dec 17 16:24"; 
[self.myArray addObject:obj]; 

obj.firstName = @"First Name2"; 
obj.lastName = @"Last Name2"; 
obj.created = @"Dec 18 7:41"; 
[self.myArray addObject:obj]; 

MyObjClass.h В меня @interface MyObjClass : NSObject. Является ли NSObject неправильным типом данных?

Недвижимость в MyObjClass.h:

@property (strong) NSString *firstName; 
@property (strong) NSString *lastName; 

И от MyObjClass.m:

@synthesize firstName, lastName; 

ответ

4

Массив не перезапись значения, вы в своем коде. У вас есть один экземпляр MyObjClass. * obj является указателем на эти объекты, и когда вы добавляете его в массив дважды, массив имеет два индекса, указывающих на объект, который вы добавили дважды.

Установив свойства на obj, вы меняете значения этого одного объекта, на которые указывает ваш указатель * obj и массив.

Почему вы обеспокоены созданием объектов X? Похоже, вы хотите, чтобы объекты X находились в массиве с различными значениями.

Помимо создания объектов X, вы можете скопировать первый объект, установить значения, затем добавить их в массив, но так как вы все равно устанавливаете все значения, я не уверен, почему вы просто не инициировали новый объект.

EDIT:

Основываясь на ваш комментарий ниже, это похоже на ваше беспокойство нескольких объектов вокруг управления памятью. Когда вы добавляете объект в массив, он сохраняет объект так после его добавления (если вы закончите с ним в этой области), затем отпустите или запустите его. Когда массив будет выпущен, он будет вызывать выпуск на всех объектах массива. Вам нужны n объектов, которые вы инициализируете или копируете - у вас все еще есть несколько. Отпустите их, а затем отпустите массив, когда он будет выпущен.

+0

Должен ли я использовать уникальные объекты, каждый раз? Возможно ли переработать этот код, чтобы он мог работать только с одним объектом? Если я использую несколько объектов, как мне их освободить из памяти после добавления их в массив? – jwhat

+0

Я отредактирую и отвечу на вопрос о памяти. – bryanmac

0

При добавлении объектов в NSMutableArray они сохраняются, а не копируются. Если вы не хотите изменить включенный объект, использовать эту последовательность кода:

self.myArray = [[NSMutableArray alloc] init]; 

MyObjClass *obj = [[MyObjClass alloc] init]; 
obj.firstName = @"First Name"; 
obj.lastName = @"Last Name"; 
obj.created = @"Dec 17 16:24"; 
[self.myArray addObject:[[obj copy] autorelease]]; 

obj.firstName = @"First Name2"; 
obj.lastName = @"Last Name2"; 
obj.created = @"Dec 18 7:41"; 
[self.myArray addObject:obj]; // if you're using it further then you need to make a copy of it again 
+0

Я не могу использовать autorelease с ARC. Можно ли просто оставить авторекламу или есть новый, другой способ убедиться, что это освобождается из памяти? Кроме того, использование [obj copy] выбрасывает эту ошибку: непризнанный селектор, отправленный в экземпляр – jwhat

+0

извините, еще не просмотрел ARC. –

+0

В любом случае, 'copy' на самом деле не может быть таким хорошим вариантом, поскольку вы перезаписываете все предыдущие значения, поэтому вместо вызова' copy, autorelease' вы можете создать новый экземпляр и добавить его (есть примеры в другие комментарии) –

0

Попробуйте установить свойство в классе MyObjClass так:

@property (copy) NSString *firstName; 
@property (copy) NSString *lastName; 
@property (copy) NSString *created; 
+1

Это не сработало. – jwhat

1

Вам нужно создать уникальный экземпляр для каждого добавленного объекта. Также в этом методе должен быть выпущен obj, потому что добавление его в массив сохраняет его. Однако, если вы используете ARC, освобождение не требуется/разрешено.

self.myArray = [[NSMutableArray alloc] init]; 

MyObjClass *obj; 

obj = [[[MyObjClass alloc] init] autorelease]; 
obj.firstName = @"First Name"; 
obj.lastName = @"Last Name"; 
obj.created = @"Dec 17 16:24"; 
[self.myArray addObject:obj]; 

obj = [[[MyObjClass alloc] init] autorelease]; 
obj.firstName = @"First Name2"; 
obj.lastName = @"Last Name2"; 
obj.created = @"Dec 18 7:41"; 
[self.myArray addObject:obj]; 
+0

В ios5 больше нет авторекламы. Я не уверен, что это просто происходит автоматически ... – jwhat

+2

Это не iOS5 или даже iOS4, это проекты на базе ARC (файлы на самом деле), которые не позволяют автозапуска, выпуска или сохранения. Не все используют ARC по разным причинам. – zaph

0

Вы недооцениваете метод и объекты -addObject: в целом. Вы добавляете ссылку (указатель) к вашему экземпляру MyObjClass в массив. Если вы добавите один и тот же экземпляр дважды, это не имеет значения. Кроме того, поскольку вы только сохраняете указатель на объект в массиве, у вас всегда есть последняя «версия» вашего объекта в массиве.

Вам необходимо выделить два экземпляра и добавить их обоих:

MyObjClass *object1 = ...; 
[array addObject:object1]; 
MyObjClass *object2 = ...; 
[array addObject:object2]; 
Смежные вопросы