Я пишу приложение для iPad, и у меня проблема с отзывчивостью / блокировкой пользовательского интерфейса.
У меня есть UITableView с элементами, при щелчке по элементу он выходит в Интернет, выбирает этот элемент и отображает его. Остальная часть программы (не показана) будет использовать загруженный элемент, поэтому одновременно можно загрузить только один элемент.
Получение элемента может занять много времени. В течение этого времени я хочу, чтобы пользователь все еще мог прокручивать UITableView, но не мог ничего выбирать, пока не будет загружен предыдущий элемент.
Я знаю, что это можно сделать с помощью потоков, блоков и обратных вызовов, но сейчас у меня нет времени, чтобы сделать это (невозможное ограничение по времени).
Я думал, что быстрым способом будет загрузить его последовательно и использовать циклы выполнения и флаг, как этот двухшаговый процесс:
Когда пользователь нажимает на ячейку таблицы, вызывается didSelectRowAtIndexPath, там я устанавливаю глобальный флаг, а затем вызываю метод загрузки для загрузки элемента. Если пользователь нажимает на другой элемент (до завершения загрузки, он увидит установленный флажок и выйдет из этой функции, не загружая ничего. В основном это:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
static BOOL alreadyInHere=FALSE;
if (alreadyInHere) return;
alreadyInHere=TRUE;
....
downloadItem(...);
ShowAndUseItem(...);
alreadyInHere=FALSE;
}
Это позволяет пользователю выбирать только один элемент за раз.
Чтобы позволить пользователю иметь возможность прокручивать UITableView во время длительной загрузки, я включил цикл выполнения в методе downloadItem (...), показанном выше, как это ...
-(void) downloadItem(....)
{
BOOL downloading=TRUE;
callFunctionsToStartdownload(...); //
while (downloading) {
downloading=DownloadSomeBytes(...);
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, YES);
}
}
Результатом (1) и (2) является то, что пользователь все еще может прокручивать UITableView во время последовательной загрузки, флаг readyInHere не позволяет ему выбрать что-либо и начать другую загрузку.
В большинстве случаев это работает, но примерно в 50% случаев во время загрузки UITableView перестает отвечать на запросы (не может перейти к другим элементам в таблице), и даже после загрузки didSelectRowAtIndexPath больше не вызывается, когда вы нажмите на что-нибудь, что сделает UITableView в основном заблокированным.
У меня вопрос, правильно ли я выполнил runLoop?
Я знаю, что есть другие способы сделать это, но я должен сделать это сейчас, используя этот общий метод, по другим причинам.
Спасибо