Быстрее, чем -forwardInvocation: выполнять сообщения в определенном потоке - PullRequest
2 голосов
/ 18 июня 2011

Для повышения скорости отклика некоторые синхронные методы, использующие FMDB для выполнения запросов SQLite в главном потоке, были переписаны как асинхронные и выполнялись в фоновом режиме с помощью -performSelectorInBackground:withObject:. SQLite не является поточно-ориентированным, однако каждый из этих методов в конечном итоге вызовет -[FMDatabase open], что приведет к снижению общей производительности.

Итак, я написал прокси для классов FMDB, который переопределил -forwardInvocation: для выполнения -[NSInvocation invokeWithTarget:] в одном конкретном потоке через -performSelector:onThread:withObject:waitUntilDone:. Это решило проблему слишком большого количества вызовов на -[FMDatabase open], но -forwardInvocation: сам по себе довольно дорогой.

Есть ли хороший способ решить эту проблему производительности, не переписывая весь код, который вызывает методы FMDB?

1 Ответ

2 голосов
/ 18 июня 2011

Вы нашли проблему: не звоните -performSelectorInBackground:withObject:! Там нет никакой гарантии, что это будет делать, но, вероятно, не будет делать правильные вещи.

Если вам нужен отдельный «поток базы данных» для фоновых операций, то есть несколько вариантов:

  • Создайте новый поток базы данных и запустите цикл и используйте вместо него -performSelector:onThread:....
  • Создайте NSOperationQueue с maxConcurrentOperationCount = 1 и используйте NSOperation (NSInvocationOperation, возможно?) Или очередь последовательной отправки. Это не совсем правильно: операции / блоки не гарантированно выполняются в одном и том же потоке, что может нарушить sqlite (IIRC вы можете перемещать дескриптор БД между потоками только после освобождения всех операторов)
  • Используйте NSOperationQueue, но сохраните локальную ссылку потока на базу данных в [[NSThread currentThread] threadDictionary]. Это немного грязно, так как у вас мало контроля над исчезновением базы данных. Это также может нарушить контракт NSOperation (вы должны вернуть поток в исходное состояние после завершения операции).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...