3

在我的应用程序中,我使用NSXMLParser从几个(6-10)网站加载信息,然后将信息加载到视图中。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:被调用,它就会将所有站点加载到对象中,然后将它们加载到视图中。

任何想法发生了什么?如果你不能说我是多线程新手。谢谢:)


编辑: 创建backgroundQueue这样的:

dispatch_queue_t backgroundQueue; 

init

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

,并释放它在dealloc

dispatch_release(backgroundQueue); 
+0

你的意思是'loadSite:'是在后台执行的线程的第一次,然后一直在主线程? 'backgroundQueue'是一个串行队列吗?你能证明你是如何创造它的吗?你有没有摧毁它? – Costique 2012-04-06 05:12:30

+0

@Costique我将这些信息附加到我的问题。对不起,我不知道它是否是一个串行队列,但我相信你可以告诉。 我几乎可以肯定'loadSite:'是第一次在后台线程上执行,然后总是在主线程上执行,但我并不积极。有什么方法可以检查吗?谢谢。 – 2012-04-06 05:20:18

+0

所以调度队列不是串行的。把'NSLog(@“%s”,[NSThread isMainThread]?“主线程”:“后台线程”);'在'loadSite:'确保它在后台被执行。你什么时候发布调度队列? – Costique 2012-04-06 05:31:36

回答

2

使用dispatch_queue_create函数创建的队列是串行队列, 然后dispatch_queue_create提交的块将按顺序执行。

使用:

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

你的建议看起来像是在工作......在主线程上完成的所有事情都被同时调用,但我认为这是因为所有的站点都在同一时间完成加载。谢谢!! – 2012-04-06 17:31:19