【问题标题】:dispacth_sync vs dispatch_async : iOS JSON parsingdispacth_sync vs dispatch_async:iOS JSON 解析
【发布时间】: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 中抽象您的下载部分以获得更清晰的代码。来回答您的问题请参阅此链接stackoverflow.com/questions/19822700/…

标签: ios objective-c json uitableview


【解决方案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. 线程 1:dispatch_async 一个耗时的任务(任务 1)到串行 排队
  2. 线程 2:开始执行任务 1
  3. 线程 1:dispatch_async 另一个任务(任务 2)到串行队列
  4. 线程 2:任务 1 已完成。开始执行任务 2
  5. 线程 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】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-12
          • 1970-01-01
          • 2011-05-16
          相关资源
          最近更新 更多