UIAlertView: wait_fences: не удалось получить ответ: 10004003 - PullRequest
1 голос
/ 04 марта 2011

Я выполняю веб-запрос в фоновом режиме и хочу, чтобы пользователь мог отменить этот запрос. Я использую UIActionSheet с кнопкой «Отмена» во время работы веб-запроса. Когда веб-запрос возвращает ошибку, я закрываю UIActionSheet, вызывая DismissWithClickedButtonIndex (0, true). Затем я показываю UIAlertView с сообщением об ошибке и возможностью отменить или повторить веб-запрос.

В большинстве случаев все работает нормально, но иногда я получаю сообщение "wait_fences: не удалось получить ответ: 10004003" в окне вывода консоли, и, случайно, возникает какое-то странное поведение пользовательского интерфейса.

Я провел некоторый поиск и обнаружил, что это вызвано чем-то вроде лежащего в основе представления, которое не может получить управление до того, как оно будет передано в UIAlertView. Некоторые люди предлагали отложить показ AlertView с помощью PerformSelector. Это правильное решение? Если это так, как я могу передать метод Show UIAlertView первому параметру метода PerformSelector?

В настоящее время я использую это решение для задержки:

private void StartAfterParentViewUpdate(NSAction action)
{
    NSAction delayedAction = () => BeginInvokeOnMainThread(action);
    NSTimer.CreateScheduledTimer(new TimeSpan(0, 0, 0, 0, 200), delayedAction);
}

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

1 Ответ

2 голосов
/ 15 апреля 2011

Чтобы ответить на мой собственный вопрос: решение работает хорошо, я больше никогда не видел сообщения wait_fences. Я сделал статический помощник для использования из любого класса:

public static class UIHelper
{
    public static void StartAfterParentViewUpdate(NSObject parent, NSAction action)
    {
        NSTimer.CreateScheduledTimer(new TimeSpan(0, 0, 0, 0, 100), () => parent.BeginInvokeOnMainThread(action));
    }

    // Use this helper method only when action is a non-static member of an object.
    public static void StartAfterParentViewUpdate(NSAction action)
    {
        StartAfterParentViewUpdate((NSObject)action.Target, action);
    }
}

Если вам нужно отложить вызов метода с параметрами, используйте анонимный делегат. Пример:

    NSAction action = () => { viewController.NavigationController.PopViewControllerAnimated(true); };
    UIHelper.StartAfterParentViewUpdate(viewController, action);
...