我在实现目标c的内存管理方面遇到了问题。我已经阅读了几本手册,但我认为我已经失去了一些东西。
我正在开发一个使用加载了查询结果的UITableView的应用程序;
-(NSMutableArray *)sqlReader:(NSString *)sqlString
{
NSMutableArray *sqlResult = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *sqlRow = [[NSMutableArray alloc] init];
sqlite3 *database;
int dataType;
int intResult;
int colCount;
int a;
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
const char *sqlStatement = [sqlString UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK)
{
[sqlResult removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW)
{
//[sqlRow removeAllObjects];
sqlRow = [[NSMutableArray alloc] init];
colCount = sqlite3_data_count(compiledStatement);
for (a=0;a<colCount;a++)
{
dataType = sqlite3_column_type(compiledStatement, a);
if (dataType == SQLITE_INTEGER)
{
intResult = sqlite3_column_int(compiledStatement, a);
[sqlRow addObject:[NSString stringWithFormat:@"%d",intResult]];
}
else if (dataType == SQLITE_TEXT)
{
[sqlRow addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, a)]];
}
else if (dataType == SQLITE_BLOB)
{
NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(compiledStatement, a) length: sqlite3_column_bytes(compiledStatement, a)];
[sqlRow addObject:[UIImage imageWithData:dataForCachedImage]];
[dataForCachedImage release];
}
}
[sqlResult addObject:sqlRow];
[sqlRow release];
}
return sqlResult;
}
}
return nil;
}
包含此函数的类用于实现UITableView的委托方法的其他类。
在这个类的UIViewController中:
声明:.h文件中的:
NSMutableArray *loadedInfo;//will contain all query results
@property (nonatomic, retain) NSMutableArray *loadedInfo;
在实施文件.m
中@synthesize loadedInfo;
- (void)viewDidLoad {
loadedInfo = [[NSMutableArray alloc] init];
//do other initializations
在其他方法中,loadedInfo用查询结果填充:
-(void)loadTemas
{
loadedInfo = [SQL sqlReader:@"SELECT * FROM TEMAS ORDER BY NOMBRETEMA;"];
//This returns an autoreleased NSMutableArray
[detail reloadData];
//This calls the delegate methods of UITableView
}
以下两个方法是UITableView的委托和用于创建返回单元格的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (searchMode == 0)
return [self setTemaCell:indexPath tableView:tableView];
else if (searchMode == 1)
return [self setItemCell:indexPath tableView:tableView];
}
#pragma mark Set Cell Functions
-(UITableViewCell *)setTemaCell:(NSIndexPath *)indexPath tableView:(UITableView *)tableView
{
UITableViewCell *customCell;
UIImageView *imgIcon;
UILabel *lblTitle;
customCell = [tableView dequeueReusableCellWithIdentifier:@"CellID"];
CGRect frame = CGRectMake(0, 0, 0, 20);
//if (!customCell)
//{
customCell = [[[UITableViewCell alloc] initWithFrame:frame reuseIdentifier:@"CellID"] autorelease];
//}
//customCell = [customCell initWithFrame:frame reuseIdentifier:@"CellID"];
customCell.selectionStyle = UITableViewCellSelectionStyleNone;
imgIcon = [[UIImageView alloc] initWithFrame:CGRectMake(10, 13, 64, 64)];
[imgIcon setImage:[self imageWithImage:[[loadedInfo objectAtIndex:indexPath.row] objectAtIndex:2] scaledToSize:CGSizeMake(64, 64)]];
//This is the line where I'm having an EXEC_BAD_ACCESS.
[customCell.contentView addSubview:imgIcon];
[imgIcon release];
imgIcon = nil;
lblTitle = [[[UILabel alloc] initWithFrame:CGRectMake(80, 30, 270, 20)] autorelease];
lblTitle.font = [UIFont systemFontOfSize:24.0];
lblTitle.textAlignment = UITextAlignmentLeft;
lblTitle.backgroundColor= [UIColor whiteColor];
lblTitle.textColor = [UIColor blackColor];
lblTitle.text = [[loadedInfo objectAtIndex:indexPath.row] objectAtIndex:1];
[lblTitle setAlpha:1];
[customCell.contentView addSubview:lblTitle];
[customCell setAlpha:1];
return customCell;
}
我已经阅读了内存管理编程指南和几个解释规则的帖子。好吧,如果我遵循规则(当一个对象必须从一个方法返回,这必须用autorelease声明)应用程序崩溃,但如果我没有应用程序内存占用高于30 MB!
我的目标是创建一个
的功能(NSMutableArray *)function_A
{
NSMutableArray *theArray = [[NSMutableArray alloc] init];
/fill the array
return [theArray autorelease];
}
来电者等级
标头中的声明一个数组
NSMutableArray *theArray;
在init函数中初始化数组
theArray = [[NSMutableArray alloc] init];
填充函数中的用返回的数组填充数组
theArray = [myclass function_A];
在不同的函数中使用此返回的数组
在dealloc函数中释放数组。
这可能吗?实现这个的最佳方法是什么?
任何帮助都会被贬低。
答案 0 :(得分:0)
在您的来电者课程中,您似乎忘记了release
旧的theArray
对象,并且您应该retain
它。
最简单的方法是在调用者类中将theArray
声明为retain
ed属性(或复制),并在设置时使用提供的setter:
self.theArray = [myclass function_A];
将调用正确的内存管理行为。
不要忘记release
中的dealloc
。
返回一个自动释放的对象很好,并且应该对该方法名称有所期待。