Синхронизированный доступ к логике UITableViewDelegate

#iphone #ios #synchronized #didselectrowatindexpath #uitableview

#iPhone #iOS #синхронизированный #didselectrowatindexpath #uitableview

Вопрос:

Я хотел бы задать вопрос о представлении таблицы и @synchronized конструкции. Я должен выполнить код внутри didSelectRowAtIndexPath один раз, даже если пользователь продолжает нажимать на ячейку таблицы…

У меня есть таблица, используемая в качестве меню в игре. Я хотел бы предоставить синхронизированный доступ к логике, реализованной в didSelectRowAtIndexPath .

Я написал следующий код:

 //condition = YES in init code

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        @synchronized( self)
        {
            if( !condition)
            {
                NSLog(@"multiple execution is not allowed...");
                return;
            }
            condition = NO;
            ...
            //code
            ...
        }
    }
  

Я протестировал его на своем ipone 3gs с ios 4.3.4 и работал (я провел тесты, и поведение соответствует ожиданиям), но мой клиент протестировал его на своем 3g с установленной ios 3.x, и, похоже, он не работает.

Я думал использовать GCD (путем вложения кода dispatch_once() ), но он поддерживается начиная с ios 4.x.

Есть ли у вас какое-либо представление о том, почему @synchronized не работает на телефоне моего клиента?

Спасибо!

Ответ №1:

@synchronized здесь не должно быть не нужно.

  • вы можете ожидать, что вызов делегата будет выполнен из основного потока (при условии, что вы его не вызываете).
  • dispatch_once здесь кажется необычным выбором. если вы уверены, что это хорошо, попробуйте pthread_once для iOS 3. это странно, потому что он работает с использованием изменяемого глобального состояния. IOW, «Я хочу создать только одну таблицу».
  • тестирование BOOL выполняется быстро.

Мое предположение? Ваша таблица удаляется (выгрузка представления) и может не быть воссоздана при перезагрузке.

Комментарии:

1. Спасибо за ваш ответ. Я подумал об использовании dispatch_once, чтобы найти способ выполнить код, связанный с однократным нажатием строки таблицы. Я проверил проблему, установив точку останова внутри реализации didSelectRowAtIndexPath, и, остановившись на точке останова, я нажал еще раз, и другой поток вошел в didSelectRowAtIndexPath, поэтому я нахожусь в состоянии гонки..

2. хммм … не уверен, что сказать, если вы уверены, что вызываете его только из основного потока. вы случайно отключили исключения objc или c ? если это так, попробуйте сделать это с включенными настройками. обычно я бы просто выделил логику в отдельный метод. в противном случае могут существовать другие части программы, которые не являются потокобезопасными, или вы можете инициализировать и уничтожать нетрадиционным способом.