2015-04-24 2 views
0

Я прочитал, что [_tableView reloadData] отправляет сообщение в основную очередь для обновления и отображения данных в представлении таблицы. Исходя из этого, я хотел бы обсудить следующий случай. Предположим, что другой метод отправляет сообщение в основную очередь до [_tableView reloadData], в этом случае второе сообщение будет обработано до [_tableView reloadData]?Выполняет ли reloadData of Tableview немедленно в этом случае

Теперь это мой случай

Пусть у меня есть две темы TA и TB и у меня есть два метода MethodA и MethodB, которые выглядят как этот

Это MethodA

- (void) MethodA 
{ 
dispatch_async(dispatch_get_main_queue(), ^{ 
        [Myarray addObject:@"SomeObject"]; 
        ///----------<TimeFrameA>---------------- 
        [_tableView reloadData] 
       }); 
} 

Это MethodB

- (void) MethodB 
{ 
dispatch_async(dispatch_get_main_queue(), ^{ 
        //Runs under the assumption the "SomeObject" has already been displayed in Tableview 
        //Make changes to TableView/ 
       }); 
} 

Предположим, что MethodB вызывается ThreadB и встречается в течение TimeFRameA. В этом случае метод B будет вызываться до [_tableView reloadData]? Есть ли какой-либо способ убедиться, что MethodB работает только в том случае, когда tableView отображает обновленные данные?

+0

Метод B может быть фактически вызван во время TimeFrameA, но асинхронная задача метода B не будет выполняться, il после вашего вызова reloadData вернулась. Однако, поскольку некоторые из действий reloadData сами запланированы, ваша задача MethodB может легко выполняться до того, как перезагрузка таблицы начнется или будет полностью завершена. Ваша основная проблема может быть связана с тем, что reloadData на самом деле закончил, когда можно безопасно выполнять метод B. Почему бы не поставить очередь блока кода в массив: тогда у вас есть таймер в основном потоке, который сбрасывает этот массив блоков, когда он знает его безопасно. Поэтому отправьте в очередь отправки. –

+0

Проблема здесь MethodA и MethodB оба вызываются делегатом. Единственное, что точно, это то, что MethodA вызывается до MethodB. Метод B можно было бы назвать почти параллельно с MethodA, а иногда и после второго или двух. Если я использую ваш подход после обновления таблицы, я бы не знал, когда вызывать метод B.возможно, потребуется вызвать его мгновенно или нет на пару секунд. Я бы не знал. – MistyD

+0

Я предлагал вам немедленно запустить метод B. Однако вместо отправки существующего кода для запуска, который может запускаться слишком рано, отправьте код, который добавляет исходный код в виде блока в очередь с некоторым тегом для объекта, который вы ожидаете визуализировать в таблице. Затем запустите таймер в главной очереди, чье задание должно очистить эти отложенные блоки: таймер смотрит в голову очереди, проверяет таблицу и выполняет ли элемент этот блок. Вы убиваете таймер, когда очередь сбрасывается. –

ответ

2

Основная диспетчерская очередь (связанная с основной нитью) - serial очередь, а не одновременно. Поэтому он не может случиться, что в

dispatch_async(dispatch_get_main_queue(), ^{ 
        [Myarray addObject:@"SomeObject"]; 
        ///----------<TimeFrameA>---------------- 
        [_tableView reloadData] 
       }); 
} 

любой другой код выполняется на главную очереди между добавлением объекта и перегрузкой вида таблицы.

Любой другой блок, отправленный в основную очередь, выполняется либо до , либо после этого блока.

0

Я бы порекомендовал вам использовать «dispatch_group» для синхронизации.

Создание объекта отправки группы по телефону:

dispatch_group_t group = dispatch_group_create(); 

При использовании Methoda:

-(void) MethodA { 
    dispatch_group_enter(group); 
    dispatch_async(dispatch_get_main_queue(), ^{ 
        [Myarray addObject:@"SomeObject"]; 
        ///----------<TimeFrameA>---------------- 
        [_tableView reloadData]; 
        dispatch_group_leave(); 
       }); 
} 

В MethodB ждать group завершить, а затем выполнить дополнительные операции:

-(void) MethodB { 
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 
     //Runs under the assumption the "SomeObject" has already been displayed in Tableview 
     //Make changes to TableView/ 
    }); 
} 
Смежные вопросы