2012-07-25 107 views
0

我有一个加速度计,用于稍微移动UIImageviews图层,以获得一些深度感。加速度计的性能问题

这里是我用来在我的viewdidload方法中实例化动画和加速度计的代码。

UIAccelerometer *accelerator = [UIAccelerometer sharedAccelerometer]; 
accelerator.delegate = self; 
accelerator.updateInterval = 0.1f; 

animateLayer0 = [CABasicAnimation animationWithKeyPath:@"position"]; 
animateLayer1 = [CABasicAnimation animationWithKeyPath:@"position"]; 
animateLayer2 = [CABasicAnimation animationWithKeyPath:@"position"];  
animateLayer0.duration = 0.1; 
animateLayer0.fillMode = kCAFillModeForwards; 
animateLayer0.removedOnCompletion = false; 
animateLayer1.duration = 0.1; 
animateLayer1.fillMode = kCAFillModeForwards; 
animateLayer1.removedOnCompletion = false; 
animateLayer2.duration = 0.1; 
animateLayer2.fillMode = kCAFillModeForwards; 
animateLayer2.removedOnCompletion = false; 

这里是加速度计功能的代码:

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{ 

self.difference = 0 - acceleration.y; 

if (fabsf(self.difference) > 0.01) { 
    for (int i = 0; i < self.accLayerPoints0.count; i++) { 
     NSValue *val = [self.accLayerPoints0 objectAtIndex:i]; 
     CGPoint origin = [val CGPointValue]; 

     float x = origin.x + (acceleration.y * ACC_LAYER0_THRESHOLD); 
     [animateLayer0 setToValue:[NSValue valueWithCGPoint:CGPointMake(x, origin.y)]]; 
     UIImageView *layer0 = [self.accLayerObjects0 objectAtIndex:i]; 
     [layer0.layer addAnimation:animateLayer0 forKey:nil]; 

    } 

    for (int i = 0; i < self.accLayerPoints1.count; i++) { 
     NSValue *val = [self.accLayerPoints1 objectAtIndex:i]; 
     CGPoint origin = [val CGPointValue]; 

     float x = origin.x + (acceleration.y * ACC_LAYER1_THRESHOLD); 
     [animateLayer1 setToValue:[NSValue valueWithCGPoint:CGPointMake(x, origin.y)]]; 
     UIImageView *layer0 = [self.accLayerObjects1 objectAtIndex:i]; 
     [layer0.layer addAnimation:animateLayer1 forKey:nil]; 
    } 

    for (int i = 0; i < self.accLayerPoints2.count; i++) { 
     NSValue *val = [self.accLayerPoints2 objectAtIndex:i]; 
     CGPoint origin = [val CGPointValue]; 

     float x = origin.x + (acceleration.y * ACC_LAYER2_THRESHOLD); 
     [animateLayer2 setToValue:[NSValue valueWithCGPoint:CGPointMake(x, origin.y)]]; 
     UIImageView *layer0 = [self.accLayerObjects2 objectAtIndex:i]; 
     [layer0.layer addAnimation:animateLayer2 forKey:nil]; 
    } 
    } 
} 

我的问题是而iPad开始有性能问题,开始落后了。 我使用了Allocations工具来验证它是导致问题的加速度计功能中的代码。

是否有办法释放不再使用的对象或清除代码? 我正在使用ARC,因此我不确定清洁是如何工作的。

回答

1

我不认为分配是你的问题。我敢打赌,如果你使用时间分析器,你会发现你用所有的加速度计活动阻塞了主线程。对于每一个加速度计事件,您都在进行一系列非常紧密的循环,这可能比您意识到的要多。

考虑将位置计算放置在后台队列中并更新主线程上UI对象的位置(这部分是必需的,因为从后台队列更新UI通常不安全)。通过将实际的UI更新命令分派给主队列来完成此操作。也许创建一个漏斗点(-updateUIWithDictionaryContainingComputedPositionsForEachLayer:,用你的背景计算值在主队列上调用)。

这也值得怀疑,你需要每一个加速度计事件。调整处理(Grand Central Dispatch也可以在那里帮助,或者简单的倒计时 - 重新启动 - 如果是新事件NSTimer),所以不是每个事件都被处理。您需要试验以找到感知的“甜蜜点”,以此作为平滑外观动画和高效响应之间的平衡点,但我敢打赌,平滑视觉效果所需的更新次数比加速度计事件的次数少得多你正在处理。

+0

我在GCD上做了一些搜索,发现了很多对NSOperation的引用。你为什么提到GCD呢?我也无法弄清楚这些工作是如何工作的。 (仍然是小白)你知道一个很好的教程,可以引导我回答吗? – Fellowsoft 2012-07-26 07:35:20

+0

GCD可以更好地控制调度任务。您将不得不深入文档并发布您分开的任何具体问题。上述方法通常是要走的路,但究竟如何实施它太宽泛,不适合单个答案。 – 2012-07-26 11:09:41