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でパフォーマンスの問題が発生し始め、遅れ始めます。割り当てツールを使用して、問題の原因となっているのが加速度計関数のコードであることを確認しました。

使用されなくなったオブジェクトを解放したり、コードをクリーンアップしたりする方法はありますか?私はARCを使用しているので、クリーニングがどのように機能するかわかりません。

4

1 に答える 1

1

割り当てはあなたの問題ではないと思います。タイム プロファイラーを使用すると、加速度計のアクティビティでメイン スレッドがブロックされていることがわかるはずです。これらすべてを、加速度計イベントごとに多数の非常にタイトなループで実行していますが、これはおそらくあなたが認識しているよりもはるかに多くなっています。

位置の計算をバックグラウンド キューに入れ、メイン スレッドで UI オブジェクトの位置を更新することを検討してください (バックグラウンド キューから UI を更新するのは一般に安全ではないため、この部分は必須です)。これを行うには、実際の UI 更新コマンドをメイン キューにディスパッチします。ファンネル ポイント (-updateUIWithDictionaryContainingComputedPositionsForEachLayer:、バックグラウンドで計算された値を使用してメイン キューで呼び出される) を作成することもできます。

また、すべての単一の加速度計イベントが必要であることも疑わしいです。処理を抑制し (Grand Central Dispatch や単純な countdown-restart-if-new-event NSTimer も役立ちます)、すべてのイベントが処理されるわけではありません。滑らかなアニメーションと効率的な応答性のバランスとして、知覚的な「スイート スポット」を見つけるために実験する必要がありますが、滑らかな視覚効果に必要な更新の数は、加速度計イベントの数よりもはるかに少ないに違いありません。処理しています。

于 2012-07-25T13:01:05.897 に答える