NSMutableDictionary, вызывающий EXC_BAD_ACCESS - PullRequest
3 голосов
/ 02 мая 2011

Я пытаюсь исправить ошибку EXC_BAD_ACCESS, которая выдается, когда я получаю доступ к NSMutableDictionary в tableView: cellForRowAtIndexPath: indexPath.Прямо сейчас это работает, когда я заполняю ridesDict методом loadHistoryFromDBExtended следующим образом:

self.ridesDict = [self loadHistoryFromDBExtended]; 

NSLog(@"rides dict %@", self.ridesDict);

Однако я не хочу вызывать [self loadHistoryFromDBExtended] для каждой загружаемой ячейки, так как словарь не будет изменятьсяЯ попытался переместить:

self.ridesDict = [self loadHistoryFromDBExtended]; 

в viewDidLoad, и теперь я получаю ошибку EXC_BAD_ACCESS при использовании:

NSLog(@"rides dict %@", self.ridesDict);

в tableView: cellForRowAtIndexPath: indexPath.Из того, что я прочитал, кажется, что у меня есть некоторые проблемы с сохранением / выпуском памяти, но я не могу понять это.Я попытался [self.ridesDict retain] в viewDidLoad после вызова метода loadHistoryFromDBExtended, но это не помогло.Я очень новичок в этом, поэтому я был бы признателен за любые указания относительно того, куда идти.

Редактировать: вот метод 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];
}

Ответы [ 3 ]

4 голосов
/ 02 мая 2011

Я написал этот блог, чтобы помочь понять и отладить EXC_BAD_ACCESS

http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

В порядке простоты

  1. Запустить сборку и анализ -- Вы получаете чистую сборку?Посмотрите на то, что он говорит, но вы можете пока игнорировать проблемы утечки - ищите проблемы отправки сообщений освобожденным объектам

  2. Запуск с NSZombiesEnabled - это делает объекты никогда не освобождаемыми, а затемпожаловаться, если сообщение отправлено объекту с retainCount 0. 0. 1014 *

  3. Включите Guard Malloc, а затем используйте специальные команды GDB для проверки целостности кучи.Проблема в том, что вам нужно пройти и сделать это до того, как вы столкнетесь, чтобы найти реальную проблему.Это может привести к сбою где-то еще ближе к вашей проблеме, хотя

2 голосов
/ 02 мая 2011

Существует множество проблем с реализацией этого метода.Проверяя, можно ли открыть db, вы освобождаете пул автоматического выпуска, но затем переходите к остальной части кода.Я предполагаю, что вы, вероятно, захотите вернуть nil в этот моментВ разделе [rs next] вы создаете NSMutableArray с +array, который создает объект с автоматическим выпуском.Таким образом, вы не должны звонить [usersDictArray release], так как это будет перевыпуск.(В каждом цикле «временные», автоматически освобожденные usersDictArray экземпляры будут сохраняться в пуле pool автоматического выпуска. Когда вы вызываете [pool drain], пул автоматического выпуска отправит всем этим временным экземплярам сообщение release).К концу у вас есть return myDictionary;, из-за чего следующие две строки никогда не будут достигнуты.В результате созданный вами пул авто-выпусков никогда не будет освобожден (вытолкнут).

Вероятно, я бы так и реализовал это:обоснование создания пула локального автоматического выпуска связано с производительностью и наличием глобального NSAutoreleasePool для поглощения конечного объекта [myDictionary autorelease] с автоматическим выпуском).

1 голос
/ 02 мая 2011

Попробуйте позвонить:

[self.ridesDict retain];

перед использованием словаря (возможно, в классе init).Не забудьте позвонить:

[self.ridesDict release];
self.ridesDict = nil;

на dealloc.

Также проверьте, правильно ли вы объявили свойство в заголовке.Это должно быть:

@property (nonatomic, retain) NSMutableArray *ridesDict;

И добавьте @synthesize ridesDict; к реализации вашего класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...