loadHistoryFromDbExtended

loadHistoryFromDbExtended

我正在尝试修复当我访问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/

10-09 01:33