Xcode показывает пользовательский индикатор прогресса при загрузке из SQLite

В моем приложении iOS я вызываю метод loadData в моем методе viewDidLoad.

loadData берет данные из локальной базы данных SQLite и заполняет массив элементов.

В другом методе showData я беру загруженные данные и показываю их на реальном экране.

- (void)viewDidLoad {
    [super viewDidLoad];
    [self loadData];
    [self showData];
}

- (void)loadData {
    //connects to local SQLite database
    //data is loaded into a NSMutableArray called 'myData'
}

- (void)showData {
    UIImage *myImage = [UIImage imageNamed:[myData objectAtIndex:0]];
    self.imageView.image = myImage;
}

Однако в настоящее время это не работает, потому что метод loadData заполняет мой массив в течение некоторого времени.

Я хотел бы показать пользовательский индикатор прогресса, который появляется на экране с вращающимся изображением, которое я сделал. Это будет появляться до завершения метода loadData, а затем будет выполняться showData.

Может ли кто-нибудь указать мне правильное направление или связать меня с способом сделать это? Спасибо вам большое!

1 ответ

Решение

Это можно сделать асинхронно, в фоновой очереди. Это может быть сложно сделать многопоточными операциями с базой данных, и одно простое решение - просто создать выделенную последовательную фоновую очередь, в которой вы будете выполнять все ваши взаимодействия с базой данных (таким образом, сами операции над базой данных выполняются в одном потоке), Таким образом, ваш фоновый процесс, который загружает данные, будет отправлять операции базы данных в эту очередь, как и любые взаимодействия с базой данных, которые вы в противном случае выполняли бы из основной очереди.

Если вы используете FMDB, вы можете сделать это с FMDatabaseQueue, который обрабатывает все это для вас. Или вы можете написать свой собственный. (Я бы посоветовал вам проверить FMDB, хотя. Если ничего другого, посмотрите, как оно работает FMDatabaseQueue и принять этот шаблон в своем собственном коде.)

Если вы сделаете это, отправив начальную загрузку в фоновую очередь, которая будет выполнять все взаимодействия с базой данных через эту отдельную выделенную последовательную очередь базы данных, просто убедитесь, что вы отправили обновления пользовательского интерфейса вашего индикатора прогресса обратно в основную очередь, поскольку все взаимодействия с пользовательским интерфейсом должны занять место в главной очереди.

Сказав это, нет абсолютно никакой причины, почему запросы к базе данных для пользовательского интерфейса должны быть настолько медленными, чтобы это все же требовалось. Интересно, стоит ли разбираться, почему код вашей базы данных такой медленный, и вы можете вообще разрубить узел Гордиана.

Типичным примером неэффективных операций с базой данных является хранение изображений в базе данных. Если вы не имеете дело с очень маленькими миниатюрными изображениями, SQLite общеизвестно неэффективен при работе с BLOB-данными. Типичное решение - хранить изображения в постоянном хранилище (например, Documents папку), и сохранять только ссылки на эти пути в базе данных. Это предлагает все виды потенциальных оптимизаций.

В своем комментарии вы упоминаете, что база данных поддерживает URL-адреса изображений. Ну, в этом случае вы можете воздержаться от получения изображений в вашем loadData рутина, и вместо этого использовать "ленивую загрузку" изображений, а именно загружать изображения точно в срок, только по мере необходимости. Вы можете достичь этого, используя UIImageView категория, которая выполняет асинхронную загрузку, такую ​​как SDWebImageили, если вы уже используете AFNetworking Вы можете использовать его UIImageView категория. Если вы воспользуетесь "ленивой загрузкой UIImage", вы, вероятно, найдете множество замечательных ссылок, учебных пособий и т. Д. Но обе эти категории обеспечивают не только простой механизм "ленивой загрузки", но также обеспечивают кэширование изображений и т. Д.

Но идеальный сценарий, вместо того, чтобы создавать представление прогресса для медленного процесса загрузки, просто рефакторинг вашего проекта, полностью устраняя это узкое место производительности. Было бы стыдно пройти через работу по созданию представления о прогрессе для неэффективного интерфейса загрузки.

Другие вопросы по тегам