dispacth_sync vs dispatch_async:iOS JSON 解析

Posted

技术标签:

【中文标题】dispacth_sync vs dispatch_async:iOS JSON 解析【英文标题】:dispacth_sync vs dispatch_async : iOS JSON parsing 【发布时间】:2016-05-10 10:16:59 【问题描述】:

我只是 ios 的初学者,所以请忽略我的愚蠢,但请清除我的疑问。 我在 UITableView 中显示解析的数据。我正在使用存储在我的 NSDictionary 中的 URL 下载给定的图像。

我需要一个很好的解释我是否应该使用

dispatch_sync(,
                dispact_async (,));

dispatch_async(,
                    dispact_async (,));

这是我用于填充 UITableview 数据的代码。

-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    CustomClassCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myCell" forIndexPath:indexPath ];

    BookMyShow *bookMyShow = [_jsonArray objectAtIndex:indexPath.row];

    cell.eventCode.text = bookMyShow.eventCode;
    cell.eventName.text = bookMyShow.eventName;





    NSURL *url = [NSURL URLWithString:bookMyShow.imageString];

    //NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    //[request setHTTPMethod:@"GET"];

    dispatch_queue_t loadQ = dispatch_queue_create("DownloadQueue", NULL);
    dispatch_sync(loadQ,
                  ^
                      NSData *data = [NSData dataWithContentsOfURL:url];
                      dispatch_async(dispatch_get_main_queue(),
                                     ^
                                         cell.myImageView.image = [UIImage imageWithData:data];
                                     );


                  );


    // [cell.imageView setImageWithURL:[NSURL URLWithString:[[array objectAtIndex:indexPath.row] objectForKey:@"image"]] placeholderImage:nil];

    //cell.imageView.image = [UIImage imageNamed:bookMyShow.imageString];

    return cell;

【问题讨论】:

这可能与这个问题无关,尝试从 cellForRowAtIndexPath 中抽象您的下载部分以获得更清晰的代码。来回答您的问题请参阅此链接***.com/questions/19822700/… 【参考方案1】:

唯一的区别是dispatch_sync只在block完成后才返回,而dispatch_async在加入队列后才返回,可能没有完成。

以下代码:

dispatch_async(_serialQueue, ^ printf("1"); );
printf("2");
dispatch_async(_serialQueue, ^ printf("3"); );
printf("4");

结果是: 它可能会打印 2413 或 2143 或 1234 但 1 总是在 3 之前

对于此代码:

 dispatch_sync(_serialQueue, ^ printf("1"); );
 printf("2");
 dispatch_sync(_serialQueue, ^ printf("3"); );
 printf("4");

结果是:1234

可能发生的事情是

    线程 1:dispatch_async 一个耗时的任务(任务 1)到串行 排队 线程 2:开始执行任务 1 线程 1:dispatch_async 另一个任务(任务 2)到串行队列 线程 2:任务 1 已完成。开始执行任务 2 线程 2:任务 2 已完成。

你总是看到 12

【讨论】:

感谢这么好的解释。它也消除了我的其他疑虑。但我也需要知道在我提供的选项中,在这种情况下,我提供的哪些选项是提高下载图像效率的更好方法。 对于下载,您可以使用 ASIHTTPRequest。检查此链接:allseeing-i.com/asihttprequest/how-to-use。它可能对您有帮助。仔细阅读【参考方案2】:

这里是伟大的example 展示了填充 TableView 的好方法。它用 Swift 编写,使用 GCD、NSOperation 和 NSOperationQueue。

【讨论】:

【参考方案3】:

尝试使用 json bcs 的 dispatch_async 当数千条记录到达 tableview 时,您可以轻松滚动 bcs dispatch_async 是灵活的。

dispatch_sync 是当数千条记录出现而不是 tableview 在您的应用程序中挂起或停止时。

【讨论】:

【参考方案4】:

唯一的区别是dispatch_sync只在block完成后才返回,而dispatch_async在加入队列后才返回,可能没有完成。

dispatch_sync 等到你的块没有完成,dispatch_async 将任务添加到队列中。

使用 dispatch_async 因为它不会在你运行日志任务时卡住你的用户界面。

【讨论】:

【参考方案5】:

由于多种原因,您所做的绝对是错误的。

细胞被重复使用。你注意到对 dequeueReusableCellWithIdentifier 的调用了吗?当您尝试存储图像时,很可能会重复使用该单元格来显示完全不同的内容。

dispatch_sync 一直等到块被执行。您正在创建一个队列,然后在其上分派一个任务,所以这绝对没有意义。只需在后台队列上调度。当您的块执行时,它首先会进行同步下载。您的代码将等待下载完成。如果您的互联网连接出现问题,呼叫失败可能需要 60 秒。 (是的,它可能会失败)。因此,您的应用将挂起 60 秒。

【讨论】:

但对于一个对象,它显示的是当前图像。你能纠正我吗?那真的很有帮助。 所以我应该只在 dispatch_sync 中设置我的图像,并且必须在其中使用 dispatch_async 吗?【参考方案6】:

您还应该查看缓存点,因为每次滚动时,都会下载图像,这对用户来说是不方便的。您必须缓存已下载的任何内容。

【讨论】:

以上是关于dispacth_sync vs dispatch_async:iOS JSON 解析的主要内容,如果未能解决你的问题,请参考以下文章

dispatch_get_global_queue vs dispatch_get_main_queue

AFnetworking Vs dispatch_aync() Vs SDWebImage 框架

(iOS) dispatch_async() 与 NSOperationQueue

Grand Central Dispatch (GCD) 与 performSelector - 需要更好的解释

Flux Dispatcher 的目的是啥(与仅具有实例方法相比)

error LNK2001: 无法解析的外部符号