のバグだと思われるものに遭遇しUICollisionBehavior
ましたUIKit
。それらを配列に追加するとUIViews
、メモリリークが発生します。重力が適用されて落下するビューのグループの 10 個のアニメーションと、囲んでいるビューの境界との衝突を作成する簡単なデモ プロジェクトをまとめました。(以下のコード) Instruments の Leaks テンプレートは、実行ごとに 9 つの 64 バイトのリークを報告します。
- (void)doAnimation
{
self.animateButton.enabled = NO;
CGFloat left = 12.0f;
NSMutableArray *items = [NSMutableArray new];
// set up an array of views and add them to the superview
while (left < self.view.bounds.size.width - 12.0f) {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(left, 70, 32, 32)];
left += 34.0f;
[self.view addSubview:view];
view.backgroundColor = [UIColor grayColor];
[items addObject:view];
}
// create a gravityBehavior and initialize with views array
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items];
[self.animator addBehavior:gravity];
// create a collisionBehavior and initialize with views array
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:items];
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];
}
// UIDynamicAnimatorDelegate method that's called when collision animation is complete
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator
{
// get a collision behavior in order to access its items for loop below
UICollisionBehavior *behavior;
for (UIDynamicBehavior *oneBehavior in animator.behaviors) {
if ([oneBehavior isKindOfClass:[UICollisionBehavior class]]) {
behavior = (UICollisionBehavior *)oneBehavior;
break;
}
}
// reset the UIDynamicAnimator property's behaviors for next run
[self.animator removeAllBehaviors];
self.dropCount++;
// remove all subviews
for (UIView *view in behavior.items) {
[view removeFromSuperview];
}
// run the animation again or break
if (self.dropCount < 10) {
[self doAnimation];
} else {
self.animateButton.enabled = YES;
}
}
作業中のアプリに衝突を実装できるようにしたいのですが、このリークにより使用できなくなります。collisionBehavior をプロパティに保存して再利用しようとしました。これにより、1 つの 64 バイト チャンクを除くすべてのメモリ リークが防止されますが、それが完了すると衝突は機能しなくなります。誰でもうまくいく回避策を提案できますか?