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,所以我不确定清洁是如何工作的。

4

1 回答 1

1

我不认为分配是你的问题。我敢打赌,如果你使用时间分析器,你会看到你用所有加速度计活动阻塞了主线程。对于每个加速度计事件,您都在许多非常紧凑的循环中完成所有这些,这可能比您意识到的要多得多。

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

您是否需要每个加速度计事件也是值得怀疑的。限制处理(Grand Central Dispatch 也可以提供帮助,或者简单的倒计时重启如果新事件 NSTimer),因此不会处理每个事件。您需要尝试找到感知的“最佳位置”,以在流畅的动画和高效的响应之间取得平衡,但我敢打赌,平滑视觉效果所需的更新数量远低于加速度计事件的数量你正在处理。

于 2012-07-25T13:01:05.897 回答