我正在尝试修复当我访问tableview:cellforrowatindexpath:indexpath中的nsmutabledictionary时引发的exc_bad_access错误。现在,当我用loadHistoryFromDbExtended方法填充ridesDict时,它可以工作,如下所示:
self.ridesDict = [self loadHistoryFromDBExtended];
NSLog(@"rides dict %@", self.ridesDict);
但是,我不想为加载的每个单元格调用[Self-loadHistoryFromDbExtended],因为字典不会更改,所以我尝试移动:
self.ridesDict = [self loadHistoryFromDBExtended];
要查看didload,现在我在使用时遇到exc_bad_access错误:
NSLog(@"rides dict %@", self.ridesDict);
在表视图中:cellforrowatindexpath:indexpath。据我所读,我似乎有一些内存保留/释放问题,但我似乎无法解决。在调用loadHistoryFromDbExtended方法之后,我在viewDidLoad中尝试了[self.rides dict retain],但这没有帮助。我对这件事很陌生,所以我很想知道该去哪里。
编辑:以下是loadHistoryFromDbExtended方法:
-(NSMutableDictionary *)loadHistoryFromDBExtended
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
FMDatabase* db = [FMDatabase databaseWithPath:[self getDBPath]];
if (![db open])
{
NSLog(@"Could not open db.");
[pool release];
}
//get users
FMResultSet *rs = [db executeQuery:@"SELECT * FROM R order by date desc"]; //query provides result set
//create result array
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
while ([rs next])
{
NSMutableArray *usersDictArray = [NSMutableArray array];
//look up names for id's
[usersDictArray addObject:[rs stringForColumn:@"rNames"]];
[usersDictArray addObject:[rs stringForColumn:@"dName"]];
[usersDictArray addObject:[rs stringForColumn:@"date"]];
[myDictionary setObject:usersDictArray forKey:[rs stringForColumn:@"rID"]];
[usersDictArray release];
}
//return usersArray;
return myDictionary;
[myDictionary release];
[pool drain];
}
最佳答案
如何实现该方法有许多问题。在检查db
是否可以打开的过程中,释放autorelease池,然后继续执行其余代码。我想你可能想在那一点上返回nil
。在[rs next]
部分中,使用NSMutableArray
创建一个+array
,这将创建一个自动释放的对象。因此,您不应该调用[usersDictArray release]
,因为这将是过度释放。(在每个循环中,“临时的”,自动释放的usersDictArray
实例将存储在pool
自动释放池中。当您调用[pool drain]
时,自动释放池将向所有这些临时实例发送一条release
消息)。最后,您有return myDictionary;
,这将导致无法到达下两行。因此,您创建的自动释放池将永远不会被释放(弹出)。
这可能就是我实现它的方式:
-(NSMutableDictionary *)loadHistoryFromDBExtended {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
FMDatabase* db = [FMDatabase databaseWithPath:[self getDBPath]];
if (![db open])
{
NSLog(@"Could not open db.");
[pool release];
return nil; // I'm assuming you should return nil here
}
//get users; query provides result set
FMResultSet *rs = [db executeQuery:@"SELECT * FROM R order by date desc"];
//create result array
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
while ([rs next])
{
NSMutableArray *usersDictArray = [NSMutableArray array];
//look up names for id's
[usersDictArray addObject:[rs stringForColumn:@"rNames"]];
[usersDictArray addObject:[rs stringForColumn:@"dName"]];
[usersDictArray addObject:[rs stringForColumn:@"date"]];
[myDictionary setObject:usersDictArray forKey:[rs stringForColumn:@"rID"]];
// [usersDictArray release];
}
[pool drain];
return [myDictionary autorelease];
}
(注意,我是如何实现这一点的,假设创建本地自动释放池的原因是为了提高性能,并且有一个全局
NSAutoreleasePool
来吸收最终的[myDictionary autorelease]
自动释放对象)。关于iphone - NSMutableDictionary导致EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5853147/