IPhone自动释放返回的NSMutableArray

时间:2011-05-02 19:25:57

标签: iphone memory-management return autorelease

我仍然相对较新的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不再表示潜在的内存泄漏,但每次代码执行时都会崩溃,说消息发送到解除分配的实例。任何帮助将不胜感激我已经花了很长时间谷歌搜索,无法看到代码有什么问题。我找到了这个帖子,但它似乎不是我的问题的答案 - crash happens when NSMutableArray is returned?

2 个答案:

答案 0 :(得分:2)

您发布的代码似乎正在正确管理内存 - 您在保留和(自动)版本之间存在一对一的关系,并且您正在使用自动释放的教科书 - 所以问题是可能调用此方法的代码需要在自动释放池启动之前retain得到的数组并从你下面拉出地毯。

如果您的代码将NSMutableArray分配给您使用@property声明的ivar,则需要将该ivar声明为

@property (retain) NSMutableArray *myStations;

如果您正在执行其他操作来存储阵列,则可能需要致电[myStations retain]。您的表视图代码也需要释放数组,可能是dealloc方法。

答案 1 :(得分:0)

如果您想使用返回的NSMutableArray作为数据源来填充表格视图中的行,那么您需要将其保留在UITableView班级(或您的{ {1}}委托类)。只要滚动视图或需要更新视图,就会重复调用它。

最简单的方法是将其作为该类中的保留属性。

UITableViewDataSource

然后,如果您想使用@property (nonatomic, retain) Tests * stationArray; 方法获取数据:

viewDidLoad

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

中访问它
numberOfRowsInSection

return self.stationArray.count;

中访问它
cellForRowAtIndexPath

当然,在dealloc ......

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

方法中的自动释放是正确的(不是init或copy方法),但是如果想要在当前事件之后使用它,则该类需要保留它。