NSMutableArray из объектов плохо себя ведет - PullRequest
1 голос
/ 22 апреля 2010

Я надеюсь, что кто-то понимает, что происходит с моим NSMutableArray.

Я читаю записи a, b, c, d из базы данных, загружаю поля в объект и добавляю объект в массив.Для этого я считываю записи в экземпляр этого объекта (tmpEvent) и добавляю объект в целевой массив (NSMutableArray myArray).

код выглядит так:

for (condition) {
     tmpEvent.field1 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 0)];
     tmpEvent.field2 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 1)];
     tmpEvent.field3 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 2)];

     NSLog(@"myArray: adding %@", tmpEvent.field1);
     [myArray addObject:tmpEvent];
}

NSLog показывает

 myArray: adding a
 myArray: adding b
 myArray: adding c
 myArray: adding d

Последующее перечисление массива (это может быть тем же или другим способом):

for (myObject *records in myArray) {
    NSLog(@"iEvents  value %@", records.field1);
}

NSLog теперь показывает:

 myArray value d
 myArray value d
 myArray value d
 myArray value d

загадка .... ???есть мысли?

1 Ответ

3 голосов
/ 22 апреля 2010

Вам нужно выделить новый «iEvent» для каждого события.tmpEvent.field1 указывает на одно и то же место в памяти для каждого последующего добавления, поэтому вы модифицируете объект, который уже сохранен в массиве.NSArray не создает новую копию объекта, просто сохраняет его указатель / адрес.

Одно исправление:

[myArray addObject: [tmpEvent copy]];

Thisпредполагается, что члены класса iEvent соответствуют NSCopy.

Другой способ - выделить новый tmpEvent для каждого события, которое вы хотите сохранить.

Вопрос: Но значит ли это, что когда я освобождаю своймассив agein мне нужно перечислить через и "вручную" освободить объекты снова?

Ответ: Вы должны отправить объект релиз после добавления его в массив, так как массив отправляет ему сохранение.Когда вы избавляетесь от массива, всем объектам отправляется релиз, поэтому вам не нужно этого делать.См. Ниже ...

Попробуйте опцию alloc в соответствии с NSCopying, в любом случае вы должны выделить объект:

for (условие) {tmpEvent = [[TmpEvent alloc] init];// Или же он инициализируется

 tmpEvent.field1 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 0)];
 tmpEvent.field2 = ...

 [myArray addObject:tmpEvent];

// NSArray сохраняет объекты, которые вы добавляете.[выпуск tmpEvent];}

---- Для соответствия NSCopy --- 1. Класс должен наследоваться от NSCopying @interface TmpEvent: NSObject ...

Реализация - (id) copyWithZone: (NSZone *) зона

  • (id) copyWithZone: (NSZone *) зона {TmpEvent * copyOfMyself = [[TmpEvent alloc] init];copyOfMyself.field1 = [self.field1 copy];.... и т. д.

return copyOfMyself;}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...