【问题标题】:Objective C: Code freezes when loading series of images目标 C:加载一系列图像时代码冻结
【发布时间】:2014-08-17 17:10:59
【问题描述】:

我第一次在论坛上发帖,但过去几个月我一直在使用这里发布的答案,发现这些答案非常有用!我还在学习目标 c,并且还在学习一些基础知识。

我的代码有几百行,所以我不想发布整个代码。代码的基本前提是将一系列随机图像加载到屏幕上的随机位置。

当我试图弄清楚如何处理这个想法时,我做了一个简单的测试版本,它会在按下按钮时添加一个气球,然后当你点击弹出气球时删除所有创建的气球图像。

这个气球代码工作得很好,然后我将这个相同的概念添加到我的主代码中。然而,现在当我只使用更大的规模时,代码将冻结在 99% 的 cpu 使用率和 18.5 MB 内存。代码从未失败,但会被冻结。较大的版本基本上只是在按下按钮而不是一个按钮时添加多个气球。有时多达 15 张图片。

这种风格的代码有什么理由不能在更大范围内工作吗?或者当代码冻结并且没有给出错误时,您如何解决问题。

.h 文件

@interface ViewController : UIViewController
{
    // Holds an array of images of the balloons
    NSMutableArray *BalloonArray;

    // Holds an array file names of the balloon PNG files
    NSMutableArray *BalloonNames;
}

-(void)AddBalloon:(id)sender;
-(void)PopBalloons:(id)sender;

@end

.m 文件

@interface ViewController ()

@end

@implementation ViewController

-(void)viewDidLoad
{
    // Allocates memory for the array
    BalloonArray = [[NSMutableArray alloc] init];

    // Allocates memory and inputs the names of the images
    BalloonNames = [NSMutableArray arrayWithObjects:[UIImage imageNamed:@"pink.png"],[UIImage imageNamed:@"blue.png"],[UIImage imageNamed:@"green.png"], nil];

    [super viewDidLoad];
}

-(void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(void)AddBalloon:(id)sender
{
    int x;  // x position of the balloon image created
    int y;  // y position of the balloon image created
    int i;  // Random index value to pull a random balloon image out

    // Random number generator for the x and y position
    x = arc4random_uniform(230) + 30;
    y = arc4random_uniform(400) + 150;

    // Random index value from 0 to 2
    // Random based on how many images there are to chose from
    i = arc4random_uniform(3);

    // Uses the image from the index value previously randomnized
    UIImage *Balloon = [BalloonNames objectAtIndex:i];

    // Places the UIImage in a UIImageView
    UIImageView *BalloonView = [[UIImageView alloc] initWithImage:Balloon];

    // Sizes the image to the correct size
    BalloonView.frame = CGRectMake(0, 0, 50, 100);

    // Centers the image using the x and y coordinates
    BalloonView.center = CGPointMake(x,y);

    // Adds the image view to the view
    [self.view addSubview:BalloonView];

    // Adds the image view to the array
    [BalloonArray addObject:BalloonView];
}

-(void)PopBalloons:(id)sender
{
    // Removes each image in the array out of the main view
    for(UIImageView *Test in BalloonArray)
    {
        [Test removeFromSuperview];
    }

    // Removes all object from the array
    [BalloonArray removeAllObjects];
}

@end

【问题讨论】:

  • 您确定您没有陷入无限循环吗?什么行为导致代码“冻结”?您可以发布调用添加气球方法的代码吗?旁注:变量和方法名称应以小写字母开头。此外,如果“sender”是 UIButton,请将其作为 UIButton 而不是 id 传递。 id 可以是任何对象,这显然是不安全的。另一个,请不要使用 iVar,使用属性。您可以在文档中查找哪些属性(气球数组和气球名称应该是属性)。
  • 帮自己一个忙,并尽量遵守通常的编码约定:方法和变量名称通常以小写字母开头。话虽如此,它在哪里冻结?您是否与调试器中断并查看它在哪里?您创建并添加了多少个子视图?
  • 我检查了无限循环并“关闭”了所有可以检查的循环。我不相信这是无限循环问题,并用换行符检查了每个循环。我对目标 c 的了解非常有限,但我认为这可能是内存分配问题。
  • 另外,关于编码约定,避免将实例变量放在标题中。它们要么是公共的,应该是属性,要么是私有的,它们应该在 .m 的类扩展中(或者更好的是,私有属性)。
  • @user3780458 -- 您在样式上有很多 cmets,但事实是您发布的代码中没有任何内容会导致应用程序冻结,因此问题出在代码的其他地方。我已经为 iPad 上的游戏编写了类似的代码,它适用于 50-100 个图像视图。

标签: objective-c memory uiimageview nsmutablearray


【解决方案1】:

使方法-(void)AddBalloon:(id)sender 在单独的线程上运行。也许你可以使用[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];。看看Apple Documentation

【讨论】:

  • 坏主意。 AddBalloon 方法中有 UIKit 调用,所有 UIKit 调用都必须在主线程上。 OP 绝对应该NOT在单独的线程上运行AddBalloon
  • @user3386109 为什么在单独的线程上执行繁重的操作而不是像问题中描述的那样冻结 UI 是个坏主意?当然 UIKit 调用可以在需要时通过 PerfromSelectorOnMainThread 在主线程上进行。跨度>
  • 是的,除了AddBalloon中唯一的繁重操作 UIKit调用。
猜你喜欢
  • 2021-10-20
  • 2020-02-26
  • 2014-07-29
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多