3

В моем приложении я загружаю информацию с нескольких (6-10) сайтов с использованием NSXMLParser, а затем загружаю информацию в представления.GCD возвращается к основной теме

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

for (NSMutableDictionary *dict in self.sitesArray) { 
    SiteData *data = [[SiteData alloc] init]; 
    [data setDelegate:self]; 
    dispatch_async(backgroundQueue, ^(void) { 
     [data loadSite:[dict objectForKey:@"SiteName"]]; 
    }); 

} 

В SiteData, я загружаю сайт, используя NSXMLParser (все методы делегата также реализованы должным образом)

-(void)loadSite:(NSString *)site{ 
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:[self fullURLForSiteName:site]]; 
    [parser setDelegate:self]; 
    [parser parse]; 
    return; 
} 

Когда NSXMLParser закончил документ и экземпляр SiteData заполняется данными сайта , он переходит к методу в моем основном контроллере представления в основном потоке.

- (void)parserDidEndDocument:(NSXMLParser *)parser{  
    dispatch_async(dispatch_get_main_queue(), ^(void) { 
     [delegate successfullyLoadedSite:self]; 
    }); 
} 

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

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

Что происходит: Один из сайтов загружает и отображает, тогда мне нужно дождаться загрузки всего остального, затем все остальные будут отображаться сразу.

Из регистрации в консоли кажется, что как только он называет successfullyLoadedSite: в главной очереди в первый раз, все запускается в основной очереди. После вызова первого successfullyLoadedSite: в главной очереди он загружает все объекты в объекты, а затем загружает их в представления.

Любые идеи, что происходит? Если вы не можете сказать, что я новичок в многопоточности. Спасибо :)


Edit: Я создаю backgroundQueue так:

dispatch_queue_t backgroundQueue; 

и в init

backgroundQueue = dispatch_queue_create("uni.que.identifier.bgqueue", NULL); 

и выпустить его в dealloc с:

dispatch_release(backgroundQueue); 
+0

ли вы имеете в виду, что 'loadSite:' выполняется на фоне потока в первый раз, а затем всегда на главном потоке? Является ли 'backgroundQueue' последовательной очередью? Можете ли вы показать, как вы его создаете? Вы когда-нибудь уничтожали его? – Costique

+0

@Costique Я приложил эту информацию к моему вопросу.Извините, я не знаю, если это очередная очередь или нет, но я уверен, что вы можете сказать. Я почти уверен, что 'loadSite:' выполняется в фоновом потоке в первый раз, а затем всегда в основном потоке, но я не уверен. Есть ли способ проверить? Благодарю. –

+0

Таким образом, очередь отправки не является последовательной. Поместите 'NSLog (@"% s ", [NSThread isMainThread]?" Main thread ":" background thread ");' in 'loadSite:', чтобы убедиться, что он выполняется в фоновом режиме, как следует. Когда вы освобождаете очередь отправки? – Costique

ответ

2

Очередь использования функции dispatch_queue_create для создания является последовательной очередью, , тогда отправленный блок отправки будет выполнен как последовательный заказ.

использование:

dispatch_queue_t backgroundQueue = 
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
+0

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

Смежные вопросы