从函数返回 NSMutableArray 的内存泄漏 [英] Memory leak with returned NSMutableArray from function
问题描述
我在实现目标 c 的内存管理时遇到了问题.我已经阅读了几本手册,但我认为我丢失了一些东西.
I'm having problems with the implementation of the memory management of objective c. I've reed several manuals, but i think that I'm loosing something.
我正在开发一个应用程序,它使用一个加载查询结果的 UITableView;
I'm developing an application that uses a UITableView that is loaded with the results of a query;
-(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 的委托方法的类不同.
The class that contains this function is used from a different class that is where the delegate methods of UITableView are implemented.
在这个类的 UIViewController 中:
In the UIViewController of this class:
在.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 填充查询结果:
In other method is where loadedInfo is filled with the query results:
-(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的delegate和一个用来创建返回cell的方法
The following two methods are the delegate of UITableView and a method used to create the returned cell
- (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!
I've readed the Memory Management Programing guide and several posts where explain the rules. Well, if i follow the rules (When an object must be returned from a method, this have to be declared with autorelease) the app crashes but if I don't the app memory occupation is higher than 30 MB!
我的目标是创建一个函数
My target is create a function where
(NSMutableArray *)function_A
{
NSMutableArray *theArray = [[NSMutableArray alloc] init];
/fill the array
return [theArray autorelease];
}
来电类
在头部声明一个数组
NSMutableArray *theArray;
在init函数中初始化数组
in init function initialize the array
theArray = [[NSMutableArray alloc] init];
在fill函数中用返回的数组填充数组
in fill function fill the array with returned array
theArray = [myclass function_A];
在不同的函数中使用这个返回的数组
in diferent functions use this returned array
在 dealloc 函数中释放数组.
in dealloc function release the array.
这可能吗?实现这一点的最佳方法是什么?
Is this possible? How is the best way to implement this?
我们将不胜感激任何帮助.
Any help will be apreciated.
推荐答案
看起来在你的调用者类中你忘记了 release
旧的 theArray
对象,你应该保留
它.
It looks like in your caller class you forget to release
the old theArray
object, and you should retain
it.
最简单的方法是在调用者类中将 theArray
声明为 retain
ed 属性(或复制),并在设置时使用提供的 setter:
Easiest would be to declare theArray
in your caller class as a retain
ed property (or copied), and when setting, use the provided setter:
self.theArray = [myclass function_A];
这将调用正确的内存管理行为.
which will invoke the correct memory management behaviour.
不要忘记在dealloc
中release
.
返回一个自动释放的对象是可以的,并且使用该方法名称应该会得到什么.
Returning an autoreleased object is fine and what one should expect with that method name.
这篇关于从函数返回 NSMutableArray 的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!