【问题标题】:Performance issues with accelerometer加速度计的性能问题
【发布时间】:2012-07-23 20:46:54
【问题描述】:

我有一个加速度计,我用它来稍微移动 UIImageview 的层,以获得一些深度感知。

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

【问题讨论】:

    标签: ios ipad memory-management automatic-ref-counting


    【解决方案1】:

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

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

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

    【讨论】:

    • 我在 GCD 上做了一些搜索,发现很多对 NSOperation 的引用。你为什么提到GCD呢?我似乎也无法弄清楚其中任何一个是如何工作的。 (仍然是菜鸟)你知道一个很好的教程可以让我找到答案吗?
    • GCD 让您可以更好地控制调度任务。您将不得不深入研究文档并单独发布您遇到的任何具体问题。上述方法通常是要走的路,但具体如何实施它太广泛了,无法放在一个单一的答案中。
    猜你喜欢
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多