IPhone автоматически освобождает возвращенный NSMutableArray - PullRequest
0 голосов
/ 02 мая 2011

Я все еще относительно новичок в разработке для iPhone, но мне показалось, что я понял основные принципы управления памятью.У меня есть метод класса, который возвращает NSMutableArray, я вызываю alloc и init для объекта, поэтому знаю, что отвечаю за его освобождение.Однако, поскольку я возвращаю массив, я предположил, что должен был использовать авто-релиз при создании объекта вместо того, чтобы освобождать его.

+(NSMutableArray *)getStations:(int)stationType {

if(database == nil){
    [self openDataBase];
}

// Create a temporary array to hold the returned objects
NSMutableArray *holder = [[[NSMutableArray alloc] init] autorelease];

// Check if the statement has been defined
if(select4 == nil) {

    const char *sql = "SELECT station_id, station_name, AVG(test_percent) FROM stations LEFT JOIN tests USING (station_id) WHERE station_type = ? GROUP BY station_id ORDER BY station_name ASC";

    if(sqlite3_prepare_v2(database, sql, -1, &select4, NULL) != SQLITE_OK){
        NSLog(@"Error while creating detail view statement. '%s'", sqlite3_errmsg(database));
    }
}

sqlite3_bind_int(select4, 1, stationType);

// Check if the statement executed correctly
while(sqlite3_step(select4) == SQLITE_ROW) {

    NSInteger primaryKey = sqlite3_column_int(select4, 0);
    Tests *station = [[Tests alloc] initWithPrimaryKey:primaryKey];
    station.station_name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(select4, 1)];
    station.average_score = [NSNumber numberWithDouble:sqlite3_column_double(select4, 2)];

    [holder addObject:station];
    [station release];
}

// Reset the detail statement.
sqlite3_reset(select4);

// Return the holder array
return holder;
}

Есть основной код - XCode больше не указывает на потенциальную утечку памяти, но вылетаеткаждый раз, когда код выполняет произнесенное сообщение, отправленное на освобожденный экземпляр.Буду признателен за любую помощь, я потратил целую вечность, гуглял и не вижу, что не так с кодом.Я нашел эту ветку, но она не является ответом на мой вопрос - происходит сбой при возврате NSMutableArray?

Ответы [ 2 ]

2 голосов
/ 03 мая 2011

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

Если ваш код назначает NSMutableArray дляivar, который вы объявили с помощью @property, этот ivar должен быть объявлен как

@property (retain) NSMutableArray *myStations;

Если вы делаете что-то еще для сохранения массива, вам может потребоваться вызвать [myStations retain].Ваш код табличного представления также должен освободить массив, вероятно, в его методе dealloc.

0 голосов
/ 03 мая 2011

Если вы хотите использовать возвращенное значение NSMutableArray в качестве источника данных для заполнения строк в табличном представлении, вам потребуется сохранить его в своем классе UITableView (или в классе делегатов UITableViewDataSource). ). Он будет вызываться повторно всякий раз, когда представление прокручивается или иным образом нуждается в обновлении.

Проще всего сделать его сохраненным свойством в этом классе.

@property (nonatomic, retain) Tests * stationArray;

Тогда, скажем, если вы хотите получить данные в вашем viewDidLoad методе:

self.stationArray = [self getStations: self.stationID]; // property retains

Доступ к нему в numberOfRowsInSection:

return self.stationArray.count;

Доступ к нему в cellForRowAtIndexPath:

Tests *station = [self.stationArray objectAtIndex:indexPath.row];

И, конечно же, в dealloc ...

[stationArray release];

Авторелиз в методе правильный (не метод init или copy), но класс должен будет сохранить его, если он захочет использовать его позже, после текущего события.

...