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 - 需要更好的解释