【问题标题】:How to efficiently show many Images? (iPhone programming)如何有效地显示许多图像? (iPhone编程)
【发布时间】:2011-01-31 05:39:17
【问题描述】:

在我的应用程序中,我需要类似粒子系统的东西,所以我做了以下操作:

当应用程序初始化时,我会加载一个 UIImage

laserImage = [UIImage imageNamed:@"laser.png"];

UIImage *laserImage 在我的控制器的接口中声明。现在每次我需要一个新粒子时,这段代码都会生成一个:

// add new Laserimage
UIImageView *newLaser = [[UIImageView alloc] initWithImage:laserImage];
[newLaser setTag:[model.lasers count]-9];
[newLaser setBounds:CGRectMake(0, 0, 17, 1)];
[newLaser setOpaque:YES];
[self.view addSubview:newLaser];
[newLaser release];

请注意,图像只有 17px * 1px 小,model.lasers 是一个内部数组,用于执行与图形输出分开的所有计算。所以在我的主绘图循环中,我将所有 UIImageView 的位置设置为我的 model.lasers 数组中的计算位置:

for (int i = 0; i < [model.lasers count]; i++) {
    [[self.view viewWithTag:i+10] setCenter:[[model.lasers objectAtIndex:i] pos]];
}

我将标签增加了 10,因为默认值为 0,我不想使用默认标签移动所有视图。

所以动画在大约 10 到 20 张图片时看起来不错,但在使用大约 60 张图片时确实会变慢。所以我的问题是:有什么方法可以优化这个而不用在 OpenGL ES 中重新开始?

【问题讨论】:

    标签: objective-c iphone uiimageview performance


    【解决方案1】:

    我建议使用 OpenGL ES 重新开始,有一个名为 cocos2d for iPhone 的优秀框架可以使这种类型的编程变得非常简单和快速。通过快速查看您的代码,您可以将激光改造成CCSprite,这是一种在场景中移动图像的简单方法。

    【讨论】:

    • 我只是快速浏览了一下 cocos2d,它看起来很强大,但我几乎完成了我的应用程序,重写会花费太多时间。您还有其他想法吗?
    【解决方案2】:

    UIImageView 用于显示单个或多个图像。因此,与其每次都创建一个 UIImageView,不如考虑创建一个新图像并将其添加到 UIImageView。

    here

    【讨论】:

    • Apple 的文档说 UIImageView 用于显示单个图像或动画一系列图像。由于我需要一次显示所有图像,因此无法使用此功能...还有其他想法吗?
    • 哦,抱歉,Thomas,我不知道从哪里开始。让我们等待社区是否有其他答案。
    • 您好 Thomas,问题可能是您没有清除绘图上下文。你能仔细检查一下吗?
    • 你指的是哪个上下文?我应该为我的所有图像启用“绘图前清除上下文”吗?父 UIView?非常感谢您的帮助!
    • 你没有向我们展示你是如何制作动画的,所以我只是猜测:-s 如果有帮助,试试这个:CGContextClearRect(UIGraphicsGetCurrentContext(), rect);
    【解决方案3】:

    似乎您正在尝试使用 UIKit API 编写游戏代码,这并不是很适合这种目的。每当您分配 UIView 时,您都在消耗设备的资源,这会导致速度变慢,因为创建对象的成本很高。不过,你可能可以通过使用 CoreAnimation 来获得你想要的性能,它非常擅长在有限的时间范围内绘制数百张图像,尽管如果你使用 OpenGL 或像 Cocos2d 这样的引擎,它仍然会好得多。

    【讨论】:

      【解决方案4】:

      正如 jeff7 和 FenderMostro 所说,您使用的是高级 API (UIKit),使用较低的 API(CoreAnimation 或 OpenGL)可以获得更好的性能。 (cocos2d 是建立在 OpenGL 之上的)

      • 最好的选择是使用 CALayers 而不是 UIImageViews,从 UIImage 中获取 CGImageRef 并将其设置为这些图层的内容。

      • 此外,您可能希望保留一个 CALayer 池,并在必要时通过隐藏/显示来重用它们。 60 个 17*1 像素的 CALayers 并不多,我已经用了数百个,不需要额外优化。

      这样,图像将已经解压缩并在视频内存中可用。使用 UIKit 时,一切都经过 CPU,更不用说创建 UIView 了,这些都是相当重的对象。

      【讨论】:

      • 这是正确答案。只要您使用 CALayers 并将每个使用相同的 layer.contents 设置为相同的 CG 图像,您的代码就可以正常工作。在 OpenGL 中重新连接你的整个游戏将是矫枉过正,你只需要不分配大量的 UIImageView,这是你实现问题的根源。见developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-21
      • 2017-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多