【问题标题】:Speed up ios function加速ios功能
【发布时间】:2011-12-14 17:47:27
【问题描述】:

我真的需要这方面的帮助! 我正在构建一个包含大量图块的地图……比如 200x200 的 50 像素小图块。这些图块位于 UIScrollView 中,因此我可以在地图上拖动自己!真的很好用吧?好吧,因为地图中的子视图太多,所以速度非常慢。

好的,所以我在滚动时加载子视图!问题是,这也需要一些时间,使滚动有点滞后/缓慢。你能帮我改进这个功能吗?我没主意了。找到了 Grand Central Dispatch,但我不知道如何使用它。

这是我的代码

-(void)loadMapTiles {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(1, queue, 
               ^(size_t row) {
                   int radiusX = 11;
                   int radiusY = 7;
                   int y = currentCoord.y-radiusY;
                   for(int x = currentCoord.x-radiusX; x < currentCoord.x+radiusX+1; x++) {
                       int currTag = mapSize.width*(y-1)+x;
                       if(![mapScroller viewWithTag:currTag]) {
                           UIImageView *mapTile = [[UIImageView alloc] initWithFrame:CGRectMake(50*x, 50*y, 50, 50)];
                           int mapNo = (rand() % 20) + 1;
                           if(mapNo > 11) {
                               mapNo = 1;
                           }

                           mapTile.image = [UIImage imageNamed:[NSString stringWithFormat:@"desert_map%d_50.gif", mapNo]];

                           //Tag the mapTile so that we can find it again!
                           [mapTile setTag:currTag];

                           [mapContentView addSubview:mapTile];
                           [mapTile release];
                       }
                       if(x == currentCoord.x+radiusX && y < currentCoord.y+radiusY) {
                           x = currentCoord.x-radiusX-1;
                           y++;
                       }
                   }
                   //Remove the other tiles outside the radius!
                   for (UIView *mapTile in [mapContentView subviews]) {
                       if(mapTile.frame.origin.x / 50 < currentCoord.x-radiusX || mapTile.frame.origin.x / 50 > currentCoord.x+radiusX || mapTile.frame.origin.y / 50 < currentCoord.y-radiusY || mapTile.frame.origin.y / 50 > currentCoord.y+radiusY) {
                           [mapTile removeFromSuperview];
                       }
                   }
               });
}

以及上面调用地图构建函数的函数:

-(void)scrollViewDidScroll:(UIScrollView *)myScrollView {  
    CGPoint newCoord = CGPointMake((int)(myScrollView.contentOffset.x + myScrollView.frame.size.width/2) /50, (int)(myScrollView.contentOffset.y + myScrollView.frame.size.height/2) /50);
    if(newCoord.x != currentCoord.x || newCoord.y != currentCoord.y) {
        currentCoord = newCoord;
        [self loadMapTiles];
    }
}  

【问题讨论】:

  • dispatch_apply(1, queue, ...) 的意义何在?我想你想要dispatch_async(queue, ^(){...})
  • 如果我这样做,我得到的只是Collection &lt;CALayerArray: 0x3dc7c0&gt; was mutated while being enumerated. :( 我不能异步编辑滚动视图吗?
  • UIKit 调用应该在主线程上

标签: objective-c ios performance uiscrollview load


【解决方案1】:

你会想看看CATiledLayer。无论您的地图有多大,它都可以让您以一种很好的方式做您想做的事。它还支持为不同的缩放级别设置不同的图像。

【讨论】:

  • 这听起来不错,但我找不到任何教程或很好的例子来说明如何将其用于小图块地图? :( 关于此的每篇文章都来自 2008 年并使用 PDF。
【解决方案2】:

我不是 obj-c 开发人员,但是...

在我不久前关于移动 Web 开发的一次演讲中,他们建议重用内存而不是分配和释放它。

除了为每个图块创建一个新的 UIImageView 之外,您是否可以为整个屏幕预先分配足够的图像并在地图滚动时更改其中的图像?

【讨论】:

    【解决方案3】:

    也许你应该尝试使用 CoreGraphics 和图层而不是滚动视图来绘制地图并滚动它。

    【讨论】:

      【解决方案4】:

      观看 WWDC 2010 视频“使用滚动视图设计应用程序”和相应的示例代码“PhotoScroller”,您将了解滚动视图中“视图重用”的大技巧。 WWDC 2011 类似名称的视频是相同技巧的延续。

      “不再在可见区域中的视图应该被重用并重新定位以显示新内容”

      在滚动时添加和删除子视图势必会导致速度变慢。相反,您应该重新定位不可见的并显示新的东西。

      滚动问题的其他常见原因是

      layer.cornerRadius layer.shadow (不设置 shadowPath) 子视图上的任何不透明度。

      始终使用核心动画在设备上分析您的代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-08
        • 2020-05-02
        • 2010-12-01
        • 2016-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-30
        相关资源
        最近更新 更多