加快ios功能

时间:2011-12-14 17:47:27

标签: objective-c ios performance uiscrollview load

我真的需要帮助! 我正在构建一个包含大量瓷砖的地图..就像200x200小50px瓷砖一样。这些磁贴位于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];
    }
}  

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

我不是开发人员,但是......

在我刚才谈到移动网络开发时,他们建议重新使用内存而不是分配和释放内存。

不是为每个磁贴创建一个新的UIImageView,你可以为整个屏幕预先分配足够的UIImageView,只是在滚动地图时更改它们中的图像吗?

答案 2 :(得分:1)

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

答案 3 :(得分:0)

观看WWDC 2010视频&#34;使用滚动视图设计应用程序&#34;以及相应的示例代码&#34; PhotoScroller&#34;在那里,你将学习&#34;查看重用&#34;的重要技巧。在scrollViews中。 类似名称的WWDC 2011视频是同一技巧的延续。

&#34;不再在可见区域内的视图应该重复使用并重新定位以显示新内容&#34;

滚动时添加和删除子视图必然会导致减速。相反,你应该只重新定位不可见的那些并展示新东西。

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

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

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