UIScrollView 花费太多时间

Posted

技术标签:

【中文标题】UIScrollView 花费太多时间【英文标题】:UIScrollView taking too much time 【发布时间】:2013-09-02 08:26:36 【问题描述】:

我试图在我的应用程序中放置一个具有 1000,000 条记录的 ScrollView,此 scrollView 将在应用程序启动时加载,因此该应用程序直到百万条 1000 000 条记录才运行,这需要很长时间,我想知道有什么方法可以在记录加载时显示应用程序和滚动视图(在添加记录时显示滚动视图),下面的代码正在使用:

    - (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self loadIt];


- (void)loadIt

    float startX = 0;
    float startY = 0;
    [_bigScroll setContentSize:CGSizeMake(320, 312500)];
    _bigScroll.pagingEnabled = NO;
    for (counter=0; counter<999999; counter++)
    
        UIButton *tester=[[UIButton alloc] initWithFrame:CGRectMake(startX, startY, 10, 10)];

        if (counter % 2 == 0) 

            [tester setBackgroundColor:[UIColor whiteColor]];

        
        else
        

            [tester setBackgroundColor:[UIColor grayColor]];
        

        [_bigScroll addSubview:tester];
        [tester release];

        if (startX == 320) 
            startX = 0;
            startY += 10;
        
        else
            startX += 10;

        NSLog(@"counter  =  %d", counter);
    


请指教。

【问题讨论】:

假设您想要使用一个collectionView,它的工作方式类似于一个tableView 并回收一些视图而不是产生10,000 个视图。如果您不使用 ios 6,请查看这个库 github.com/steipete/PSTCollectionView,有些家伙制作了适用于 iOS4.3+ 的开源版本。 还有一些简单的事情,比如用颜色保存变量而不调用 nslog 可能会加快速度。 我建议..而不是一开始就加载所有记录,您可以先加载几条记录,然后在用户滚动并删除以前的记录时继续向其中添加记录,这将消耗更少内存......这个想法类似于tableView的单元重用概念。 对于这种类型的实现,你必须使用 UITableView 而不是 UIScrollview。 【参考方案1】:

有没有办法在记录加载时显示应用程序和滚动视图?

尝试使用[self performSelector:@selector(loadIt) withObject:nil]; or [self performSelector:@selector(loadIt) withObject:nil afterDelay:0.2]; 在执行此方法之前,它不会阻塞您的 UI。

您正在加载大量记录。实际上,您不应该一次加载所有记录。您应该使用类似 tableview 的机制,即仅加载滚动视图可见区域中的那些记录。在滚动之前不要加载新行,您应该重用行或视图以加快滚动速度。

【讨论】:

你摇滚,我有你的想法,这就是我要做的:) 你有什么简单的方法可以在滚动结束时滚动其他人吗? 不确定你在问什么。 您在这里所做的只是在稍后通过长时间操作阻塞您的 UI 线程 - 这也会导致糟糕的用户体验。 " 我需要滚动视图,因为我在每行中显示 32 个大小为 10x10 的分隔按钮,请问您有什么建议吗?"我的建议是,重新设计你的应用,这听起来像是一场可用性灾难。【参考方案2】:

Apple 的documentation for UIScrollView 非常清楚滚动视图应该是平铺的,您的应用程序在视图滚动时提供平铺。

管理滚动视图中显示的内容绘制的对象应该平铺内容的子视图,这样视图就不会超过屏幕的大小。当用户在滚动视图中滚动时,此对象应根据需要添加和删除子视图。

这对于性能和内存使用都是必需的:可滚动视图由CALayer 支持,而CALayer 又由位图支持。对于创建的每个 UIButton 对象也是如此。

虽然这需要很长时间并不奇怪,但您的应用并未因使用过多内存而被终止更是一个谜。

UITableViewUICollectionView 都是平铺其内容的视图示例。您可能会发现可以使用其中一种来实现您的要求,如果没有,请遵循他们使用的模型。

【讨论】:

【参考方案3】:

您不需要创建 1000,000 个视图。您可以动态创建视图并删除以前在屏幕空间中不可见的视图。因此,在滚动时,您可以创建新视图并删除那些不在屏幕可见区域的视图。 这将帮助您节省内存,否则无论您是否在项目中使用 ARC,如果您在内存中加载那么多视图,肯定会有崩溃的机会,在这种情况下,ARC 不会帮助您。

【讨论】:

【参考方案4】:

一旦尝试这个改变代码中的

-viewdidload()

    [self loadIt];//change this to 
    [self performSelectorInBackground:@selector(loadIt) withObject:nil];

【讨论】:

顺便说一句:那应该是-(void) viewDidLoad()

以上是关于UIScrollView 花费太多时间的主要内容,如果未能解决你的问题,请参考以下文章

缩放和重绘 UIScrollView 内容后设置 contentOffset

在 UIScrollview 中禁用对角线拖动

更改界面方向时UIScrollView上的奇怪跳转(ATPagingView)

如何在 ios 中为 UIScrollView 设置对齐方式

限制UIScrollView中的可滚动区域

自动滚动 UIScrollView 以适应原生 iOS Mail.app 中的内容