Ios 使用UIImageViews和frames或CALayers或其他工具?

Ios 使用UIImageViews和frames或CALayers或其他工具?,ios,performance,memory-management,core-animation,Ios,Performance,Memory Management,Core Animation,因此,我制作了一个非常简单的iOS游戏,它有多个对象在屏幕上滚动,并在途中检查碰撞情况。目前要移动它们,我有一个NSTimer,大约每0.01秒触发一次,并将帧移动2像素。然后,它会检查播放器的位置是否存在相交帧,并相应地进行操作 这项功能非常好,我在自己的设备上也没有问题,但我注意到,当屏幕上有20多个对象同时在较旧的设备上移动时(例如iPad 3),有时会出现延迟 在分析应用程序之后,似乎有大约70%的CPU用于这一个线程。这正常吗?如果我将每个对象添加到单个固定视图上的CALayer并更

因此,我制作了一个非常简单的iOS游戏,它有多个对象在屏幕上滚动,并在途中检查碰撞情况。目前要移动它们,我有一个NSTimer,大约每0.01秒触发一次,并将帧移动2像素。然后,它会检查播放器的位置是否存在相交帧,并相应地进行操作

这项功能非常好,我在自己的设备上也没有问题,但我注意到,当屏幕上有20多个对象同时在较旧的设备上移动时(例如iPad 3),有时会出现延迟


在分析应用程序之后,似乎有大约70%的CPU用于这一个线程。这正常吗?如果我将每个对象添加到单个固定视图上的CALayer并更新该层上的位置,而不是在屏幕上同时移动25-30个单独的UIImageView,会不会减少CPU的负载?还是有更好的方法

我想在我费尽心思将所有代码转换为层之前,我应该先问一下。有没有人有过在旧设备上编写这样一款游戏的经验

我想支持尽可能多的设备,但旧的设备似乎很难运行这个(我觉得奇怪,因为与我制作的其他一些设备相比,这个游戏非常简单)

其他信息: 部署目标:5.0
iPad设备iOS:7.0.6
iPhone 5设备iOS:7.0.6
XCode版本:5.0.2


这是启动计时器时运行的代码
CView
基本上是一个UIImageView,带有一些额外的int/bool属性

for(CView* c in self.view.subviews)
{
    if(![c isKindOfClass: [CView class]])
    {
        continue;
    }
    
    [c setFrame:[CRect rect:c.frame withNewY:c.frame.origin.y+2]];
    
    if(fabsf(c.frame.origin.y + c.frame.size.height - (player.frame.origin.y+player.frame.size.height)) <= player.frame.size.height)
    {
        if([player collideWith:c.x])
            [self gameOver];
    }
    else if((c.frame.origin.y + c.frame.size.height) > (player.frame.origin.y + player.frame.size.height) && c.passed == NO)
    {
        c.passed = YES;
        score++;
    }
    
    if(c.frame.origin.y > [CRect height])
    {
        [self removeView:c];
    }
}

if(score != score2)
    [scoreLabel setText:[NSString stringWithFormat:@"%d",score]];

score2 = score;

reps++;
if(reps < 0)
    return;

NSArray* formation = [formations objectAtIndex:(int)[Global randomFloatBetween:0 andLarge:11.99]];

float max = 0;

for(int i = 0; i < formation.count; i++)
{
    if([[formation objectAtIndex:i] intValue] == -1)
        continue;
    
    if([[formation objectAtIndex:i] floatValue] > max)
        max = [[formation objectAtIndex:i] floatValue];
    
    float x = [CRect centerX:(player.laneWidth*5)+(player.lineWidth*4)] + ((i) * (player.xWidth+player.lineWidth)) + player.margin;
    float y = -101 + ([[formation objectAtIndex:i] floatValue] * (-130));
    
    CView* c = [[CView alloc] initWithFrame:CGRectMake(x, y, 49, 101)];
    [c setX:i+1];
    [c setImage:[images objectAtIndex:(int)[Global randomFloatBetween:0 andLarge:images.count-0.01]]];
    [self.view insertSubview:c belowSubview:adBanner];
}

reps = (-101 * (max+1)) - 202;
reps /= 1.75;
for(self.view.subview中的CView*c)
{
如果(![c是类的种类:[CView类]])
{
继续;
}
[c setFrame:[correct rect:c.frame with newy:c.frame.origin.y+2];
if(fabsf(c.frame.origin.y+c.frame.size.height-(player.frame.origin.y+player.frame.size.height))(player.frame.origin.y+player.frame.size.height)和&c.passed==否)
{
c、 通过=是;
分数++;
}
如果(c.frame.origin.y>[正确高度])
{
[自我移除视图:c];
}
}
如果(得分!=得分2)
[scoreLabel setText:[NSString stringWithFormat:@“%d”,分数]];
分数2=分数;
reps++;
如果(重复次数<0)
返回;
NSArray*formation=[formations objectAtIndex:(int)[全局随机数介于0和11.99之间];
浮动最大值=0;
对于(int i=0;imax)
max=[[formation objectAtIndex:i]floatValue];
float x=[correct centerX:(player.laneWidth*5)+(player.lineWidth*4)]+((i)*(player.xWidth+player.lineWidth))+player.margin;
float y=-101+([[formation objectAtIndex:i]floatValue]*(-130));
CView*c=[[CView alloc]initWithFrame:CGRectMake(x,y,49101)];
[c setX:i+1];
[c setImage:[images objectAtIndex:(int)[全局随机数介于:0和大型:images.count-0.01]];
[self.view insertSubview:c belowSubview:adBanner];
}
重复次数=(-101*(最大+1))-202;
重复次数/=1.75;


这可能与我以这种方式创建
CViews
并在它们离开屏幕时将其置零有关吗?如果我使用一个固定的数字,只需重新使用旧的
CViews
(只需将它们放在屏幕的另一端,并在它们完成交叉时重新运行它们),这会提高性能吗?我不知道ARC收集垃圾的频率。

你应该考虑使用现有的游戏引擎,比如COCOS-2,或者花些时间使用常用的模式和最佳实践来改进你自己的引擎。如果您决定使用现有的引擎,除了阅读他们的文档并在遇到问题时询问具体问题之外,没有什么可说的。不要问关于使用什么发动机的问题。这种问题不适合堆栈溢出

如果您继续使用自己的引擎,那么我仍然建议您学习cocos-2d和Sprite工具包的文档和编程指南。这将帮助您构建自己的引擎。例如,这是《精灵工具包编程指南》中解释游戏循环的图像

如果您对使用核心动画编写游戏引擎感兴趣,那么我建议您阅读。这已经有几年了,但应该仍然是最相关的

当您将游戏引擎结构化为以下步骤时

  • 更新(移动对象)
  • 操作(响应用户交互)
  • 模拟(碰撞检测)
  • 渲染
  • 然后,您可以开始测量不同步骤的性能和内存效率,并继续处理最重的部分,直到达到可接受的性能

    当视图移出屏幕时,也许值得重用视图,也许碰撞检测太昂贵,应该优化,也许移动到层是值得的。你必须先衡量一下,知道在哪里花费你的时间和精力

    但是,我会告诉您,您应该删除NSTimer,并为游戏循环使用单个Cadisplay链接,以保持更新与显示同步


    作为旁注:

    我不知道ARC多久收集一次垃圾


    这句话使我担心。这表明您还不了解ARC是什么以及它是如何工作的ARC不是垃圾收集器。我建议您回去再看看Objective-C中的内存管理

    嗯,这可能是个愚蠢的问题。但这听起来像是UIKit Dynamics的工作。你不使用它有什么特别的原因吗?@Murillo我的无知…什么是UIKit动力学?在谷歌快速搜索之后,看起来UIKit Dynamics是针对7.0+的;我想为5.0+构建iOS 7的新物理引擎。它处理各种物理问题