ios - 我的大中央调度使用 : Am I using it correctly?

标签 ios grand-central-dispatch

我正在以 JSON 格式从服务器获取数据。它只有大约 150 条记录,我最初没有使用 GCD,但时不时地,当我点击应用程序中的按钮以查看包含数据的表格时,它会延迟大约几秒钟,然后切换到表格 View 并显示数据.所以我实现了 GCD,现在当我按下按钮时,它会立即切换到 tableview,但是加载数据会有几秒钟的延迟,这似乎比预 GCD 实现要长。所以我不确定我是否正确使用了 GCD,或者是否是我的服务器导致了延迟(我认为这是罪魁祸首)。这是 GCD 在名为 retrieveData 的方法中的实现,我在 viewDidLoad 中将其称为 [self retrieveData]:

- (void)retrieveData
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

        NSURL *url = [NSURL URLWithString:@"http://MY_URL/JSON/document.json"];
        NSData * data = [NSData dataWithContentsOfURL:url];

        dispatch_async(dispatch_get_main_queue(), ^{

    json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

    //Set up our exhibitors array
    exhibitorsArray = [[NSMutableArray alloc] init];

    for (int i = 0; i < json.count; i++) {
        //create exhibitors object
        NSString * blabel = [[json objectAtIndex:i] objectForKey:@"BoothLabel"];
        NSString * bName = [[json objectAtIndex:i] objectForKey:@"Name"];
        NSString * bURL = [[json objectAtIndex:i] objectForKey:@"HyperLnkFldVal"];


        exhibitors * myExhibitors = [[exhibitors alloc] initWithBoothName: bName   andboothLabel: blabel andBoothURL: bURL];

        //Add our exhibitors object to our exhibitorsArray
        [exhibitorsArray addObject:myExhibitors];

        //Sort by name
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
        [exhibitorsArray sortUsingDescriptors:[NSMutableArray arrayWithObject:sort]];

    }

    [self.myTableView reloadData];

        });
    });

}

最佳答案

这基本上是正确的。将数据检索分派(dispatch)到后台队列,然后将模型和 UI 更新分派(dispatch)回主队列。干得好。

就速度较慢而言,我看不出有任何原因可以解释这一点。 GCD 引入了一些开销,但通常无法观察到。这可能有点像“看着水壶永远不会沸腾”的问题。

不过,还有一些不相关的想法:

  1. 我可能建议将排序移到 for 循环之外,但在 reloadData 之前。您将其排序 150 次。如果进行插入排序,您可以在循环内进行,但我认为这里不会发生这种情况。我会把排序移到循环的末尾。我不确定是否可以观察到性能提升,但应该会有一些适度的改进。

  2. 您可能想确保 data 不是 nil(例如,没有网络,或其他一些网络问题),因为如果是, JSONObjectWithData 会崩溃。

  3. 您的json 对象是一个外部变量。它可能应该是您的 retrieveData 方法的局部变量。无需将其设为实例变量。如果合适,将其设为局部变量会更简洁。

  4. 您可能应该采用类名以大写字母开头的命名约定(例如,Exhibitor 而不是 exhibitors)。

  5. 非常小的一点,但是您的 blabel 变量可能应该是 bLabel。更好的是,我可以重命名这三个变量 boothLabelboothNameboothUrlString

  6. 您正在为 exhibitorsArray 使用实例变量。我想你也在其他地方这样做。您可能需要考虑使用 declared properties相反。

  7. 您可能希望在将代码分派(dispatch)到后台之前打开网络事件指示器,并在执行 reloadData 时将其关闭。

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    
  8. 如果你想变得非常复杂,你可能会重新考虑是否要使用 GCD 的全局队列(因为如果你快速刷新 10 次,所有十次都会运行,而你可能只希望最后一次运行) .这是一个更复杂的话题,所以我不会在这里介绍,但如果你有兴趣,你可能想引用操作队列的讨论 Concurrency Programming Guide ,您可以在其中创建可取消的操作(因此,在启动新操作时,取消之前的操作)。

    您可能还想引用 Building Concurrent User Interfaces on iOS WWDC 2012 视频。

但这与您最初的问题完全无关:是的,您已经适本地解决了这个问题。

关于ios - 我的大中央调度使用 : Am I using it correctly?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17951601/

相关文章:

ios - 子类化 UITableViewCell 不显示添加的样式

swift - 制作 GMSMarkers 时无法更新 UI

ios - SpriteKit,把一个进程放在另一个核心上?

c - 如何从 Swift 调用 dispatch_benchmark

ios - 无法使用中央调度提高ios应用程序的运行速度

ios - didUpdateToLocation 未在应用程序中调用

ios - 强制设置核心数据检查点?

ios - 快速从json获取位置

ios - 修改 awakeFromFetch 中的排序键不会更新排序顺序

ios - 需要有关 dispatch_sync 和 dispatch_async 的帮助