GCD回到主线程

时间:2012-04-06 04:52:12

标签: objective-c ios multithreading nsxmlparser grand-central-dispatch

在我的应用程序中,我使用NSXMLParser从几个(6-10)网站加载信息,然后将信息加载到视图中。

现在,我的应用程序已设置好,以便在我的主视图控制器中循环遍历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);

1 个答案:

答案 0 :(得分:2)

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

使用:

dispatch_queue_t backgroundQueue =
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);