[英]Does adding many many subviews to a viewcontrollers default view make my app slow?

I have an app where I create many uiviews and add them to the self.view of the UIViewController. My app is running really slowly. I am releasing all of my objects and have no memory leaks (I ran the performance tool). Can anyone tell me what could be making my app so slow? (code is below)

我有一个应用程序,我创建了许多uiviews并将它们添加到UIViewController的self.view。我的应用运行速度非常慢。我正在释放所有对象并且没有内存泄漏(我运行了性能工具)。谁能告诉我什么可能让我的应用程序这么慢? (代码如下)

[EDIT] The array has around 30 items. [/EndEdit]

[编辑]阵列有大约30项。 [/ EndEdit中]

Thanks so much!


Here is the code for the loadView method of my UIViewController:


- (void)loadView {

    UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    contentView.backgroundColor = [UIColor whiteColor];
    self.view = contentView;
    [contentView release]; 

    int length = 0;
    for(NSString *item in arrayTips)
        [item release];
    int index = 0;
    for(NSString *item in arrayTitles)
        SingleFlipView *backView = [[SingleFlipView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];

        backView.userInteractionEnabled = YES;
        backView.backgroundColor = [UIColor whiteColor];
        [backView setViewIndex:index];
        [backView setLastViewIndex:length];
        CGRect labelFrame = CGRectMake(10.0f, 0.0f, 300.0f, 30.0f);
        UILabel *backLabel = [[UILabel alloc] initWithFrame:labelFrame];
        backLabel.textAlignment = UITextAlignmentCenter;
        backLabel.userInteractionEnabled = YES;
        backLabel.text = item;
        backLabel.font = [UIFont fontWithName:@"Georgia" size:24.0f];
        backLabel.textColor = [UIColor blackColor];
        backLabel.backgroundColor = [UIColor whiteColor];

        CGRect textFrame = CGRectMake(10.0f, 30.0f, 300.0f, 110.0f);
        UITextView *tbxView = [[UITextView alloc] initWithFrame:textFrame];
        tbxView.textAlignment = UITextAlignmentCenter;
        tbxView.userInteractionEnabled = YES;
        tbxView.editable = FALSE;
        tbxView.text = [arrayTips objectAtIndex:index];
        tbxView.font = [UIFont fontWithName:@"Arial" size:14.0f];
        tbxView.textColor = [UIColor blackColor];
        tbxView.backgroundColor = [UIColor whiteColor];

        //CGRect labelFrame = CGRectMake(10.0f, 0.0f, 84.0f, 30.0f);
        UIImage *nextTip = [[UIImage imageNamed:@"NextTip.png"] retain];
        UIImageView *nextTipView = [ [ UIImageView alloc ] initWithImage:nextTip];
        nextTipView.frame = CGRectMake(230.0f, -10.0f, 84.0f, 30.0f);
        nextTipView.userInteractionEnabled = YES;

        UIImageView *view = [[ UIImageView alloc ] init];
        view.userInteractionEnabled = YES;
        if(self.sexString == @"Men")
            UIImage *imgTip = [[UIImage imageNamed:@"feet_small.jpg"] retain];
            view.image = imgTip;
            view.frame = CGRectMake(0.0f, 110.0f, 416.0f, 228.0f); //59*161
            [imgTip release];

        [backView addSubview:view];
        [backView addSubview:tbxView];
        [backView addSubview:backLabel];
        //[backView addSubview:nextTipView];

        [self.view addSubview:backView];
        [backView release];
        [backLabel release];
        [nextTip release];
        [nextTipView release];
        [tbxView release];
        [view release];


        [item release];


3 个解决方案



Having deep view hierarchies can lead to slow downs that you can often fix through flattening them some with custom views, but if you are using simple views you can have dozens on the screen with no perceptible performance impact, so in general I recommend ignoring how many views you have when you are developing, and then reducing the view count if it proves to be a performance problem.


Having said that, you appear to be setting up something with an unboundedily large number of views which is not good. Without knowing how many entries there are in array titles I can't tell you what is going on exactly, but I suspect that while the actual visual heiarchy with each backView you are creating is fine, making a backView for each item in the array and using indices to have the front most one hide all the other ones behind it is causing you to have way too many views.


So, how to test it:


Add a break to the bottom of your for loop. Make the loop drop out after a single iteration and see if performance improves. If it does, then the huge view hierarchies are your issue. YOu may have to hack up the routine that changes the indexes to make sure it never swaps to an invalid index to test.


If that is the case you have a few options. You could implement a custom view and flatten every backview into a single view, but depending on how many you have that mat not be sufficient, and it is more work than simply building the back views the way you currently are, but on demand instead of at load time:


1) Refactor the code in your for loop into a separate method that makes a backView for a specific title and attaches it to the view at that time. 2) Where ever you are currently altering the indexes to make the backview visible, instead call the new method to actually build and attach the backview at that time

1)将for循环中的代码重构为一个单独的方法,该方法为特定标题创建一个backView,并将其附加到视图中。 2)你当前正在改变索引以使后视图可见,而是调用新方法来实际构建并附加当时的后视图



It's going to depend upon how many items are in arrayTitles. If you're just adding one or two of these, you shouldn't see a HUGE slowdown; more, and you will. You should probably take a look at the way UITableView handles its cells; only create these as they're actually needed/used, or, better yet, only create one of these, and set its contents on-the-fly.


A few other notes:


  • == is not a valid string comparison operator in Objective-C; use [string1 isEqualTo: string2]
  • ==不是Objective-C中有效的字符串比较运算符;使用[string1 isEqualTo:string2]

  • It appears you're trying to place a lot of these on screen at the same time, which doesn't seem like it would make a lot of sense.
  • 看起来你正试图在屏幕上同时放置很多这些,这似乎没有多大意义。

  • it looks like you've got a spurious [item release] at the end there (you're never retaining item, so there's no need to release it.
  • 看起来你在那里有一个虚假的[物品释放](你永远不会保留物品,所以没有必要释放它。

  • the whole first loop ( for(NSString *item in arrayTips)... frightens and confuses me; items in NSArrays are already retained by the array. You shouldn't have to explicitly retain/release them in this way.
  • 整个第一个循环(for(NSTtring * item in arrayTips)...吓坏我并混淆我; NSArrays中的项已经被数组保留了。你不应该以这种方式显式保留/释放它们。



Don't forget to make as many of your views opaque as you can. Transparent views are a major source of performance issues.





© 2014-2019 ITdaan.com 粤ICP备14056181号