NSArray действует странно с объектами, выходящими из области видимости - PullRequest
2 голосов
/ 25 марта 2010

У меня странные проблемы с NSArray, когда некоторые члены объектов в моем массиве выходят из области видимости, но не другие:

У меня есть простой объект под названием Section. У этого есть 3 участника.

@interface Section : NSObject {
    NSNumber *section_Id;   
    NSNumber *routeId;
    NSString *startLocationName;
}
@property(nonatomic,retain)  NSNumber *section_Id;  
@property(nonatomic,retain)  NSNumber *routeId;
@property(nonatomic,retain)  NSString *startLocationName;
@end


@implementation Section

@synthesize section_Id; 
@synthesize routeId;
@synthesize startLocationName;

//Some static finder methods to get list of Sections from the db
+ (NSMutableArray *) findAllSections:{


- (void)dealloc {
    [section_Id release];
    [routeId release];
    [startLocationName release];

    [super dealloc];
}

@end

Я заполняю его из базы данных методом findAllSection

self.sections = [Section findAllSections];

В поиске всех разделов я создаю некоторые локальные переменные, заполняю их данными из базы данных.

NSNumber *secId = [NSNumber numberWithInt:id_section];
NSNumber *rteId = [NSNumber numberWithInt:id_route];
NSString *startName = @"";

Затем создайте новый раздел и сохраните данные этих локальных переменных в разделе

Section *section = [[Section alloc] init];

section.section_Id = secId;
section.routeId = rteId;
section.startLocationName = startName;

Затем я добавляю секцию в массив

[sectionsArray addObject:section];

Затем я очищаюсь, освобождая локальные переменные и раздел, добавленный в массив. [второй релиз]; [версия выпуска]; [выпуск startName]; [locEnd_name release];

[section release];

В цикле повторите для всех разделов (освобождение локальных переменных и раздел выполняется в каждом цикле)

Метод возвращается, и я проверяю массив и все разделы там. Я не могу копать дальше, чтобы увидеть значения объектов Section в массиве (это возможно)

Позже я пытаюсь получить один из разделов

Я получаю его из массива

Section  * section = [self.sections objectAtIndex:row];

Затем проверьте значение

NSLog(@" SECTION SELECTED:%@",section.section_Id);

Но звонок на section.section_Id завершился с ошибкой, так как section.section_Id выходит за рамки.

Я проверяю других членов этого объекта Секции, и они в порядке. После некоторых проб и ошибок я обнаружил, что, комментируя выпуск переменной-члена, объект в порядке.

//[secId release];
[rteId release];
[startName release];
[locEnd_name release];


[section release];

Мои вопросы:

Я убираюсь хорошо?

Должен ли я освободить объект, добавленный в массив, и локальную переменную в функции?

С моим деллоком все в порядке?

Этот код выглядит нормально, и я должен искать проблему в другом месте?

Я не делаю ничего сложного, просто заполняя массив из БД, использую его в ячейке таблицы.

Я могу закомментировать выпуск, но предпочел бы знать, почему это работает, и если я не должен был делать это. Единственное место, где высвобождается secId, находится в розыгрыше.

Ответы [ 3 ]

4 голосов
/ 25 марта 2010

Вы не должны выпускать secId, rteId или startName. secId и rteId - это указатели на NSNumber экземпляры, созданные с помощью фабричного метода, который возвращает уже автоматически выпущенный объект. Статические строки (т. Е. @"") освобождать не нужно. Вам необходимо перечитать Руководство по программированию управления памятью . Тогда прочитайте это снова ;-) Это будет ваш друг.

3 голосов
/ 25 марта 2010

Вы выпускаете объекты, которые вам не принадлежат. Вам следует прочитать правила управления памятью .

2 голосов
/ 26 марта 2010

Я буду вторым (третьим) предложением прочитать правила управления памятью.

Версия TL; DR - это все, что вы alloc и вызываете методом с init в названии метода, это ваша ответственность за освобождение. Например:

NSString *string = [[NSString alloc] initWithFormat:@"%@", someObject];

В этом случае вы должны отпустить string. Тем не менее:

NSString *string = [NSString stringWithFormat:@"%@", someObject];

Здесь string автоматически выпущен. Это в основном эквивалентно этому:

NSString *string = [[[NSString alloc] initWithFormat@"%@", someObject] autorelease];

... означает, что в следующий раз через цикл обработки событий (что, возможно, означает, что как только ваша функция вернется), система отправит вам сообщение release. Apple называет эти «удобные методы».

Если у вас есть что-то вроде этого:

NSString *string = @"foo";

Тогда string указывает на экземпляр NSString, который создается во время выполнения, когда ваша программа инициализируется, и не выйдет из области видимости, пока ваша программа не завершится. Никогда release это тоже.

Опять же, прочитайте рекомендации и добавьте их в закладки. Но это должно ответить на ваш прямой вопрос.

...