Я использую FMDB для работы с моей базой данных, которая отлично работает. Приложение использует фоновый поток, который выполняет некоторую работу и нуждается в доступе к базе данных. В то же время основной поток должен выполнять некоторые запросы к той же базе данных. Сам FMDB имеет небольшую систему блокировки, однако я добавил еще одну в свои классы.
Каждый запрос выполняется только в том случае, если мой класс указывает, что база данных не используется. После выполнения действий база данных разблокируется. Это работает, как и ожидалось, пока нагрузка не слишком высока. Когда я обращаюсь к большому количеству данных с потоком, работающим в основном потоке, возникает ошибка EXC_BAD_ACCESS.
Вот смотрю:
- (BOOL)isDatabaseLocked {
return isDatabaseLocked;
}
- (Pile *)lockDatabase {
isDatabaseLocked = YES;
return self;
}
- (FMDatabase *)lockedDatabase {
@synchronized(self) {
while ([self isDatabaseLocked]) {
usleep(20);
//NSLog(@"Waiting until database gets unlocked...");
}
isDatabaseLocked = YES;
return self.database;
}
}
- (Pile *)unlockDatabase {
isDatabaseLocked = NO;
return self;
}
Отладчик говорит, что ошибка возникает на [FMResultSet next]
в строке
rc = sqlite3_step(statement.statement);
Я дважды проверил все счетчики сохранения, и все объекты действительно существуют в это время. Опять же, это происходит только тогда, когда основной поток запускает множество запросов во время работы фонового потока (который сам по себе всегда создает большую нагрузку). Ошибка всегда создается основным потоком, а не фоновым потоком.
Моя последняя идея заключалась бы в том, чтобы оба потока запускали lockedDatabase одновременно, чтобы они могли получить объект базы данных. Вот почему я добавил блокировку мьютекса через «@synchronized(self)». Однако это не помогло.
Кто-нибудь знает?