I've run into what I believe is a bug with UICollisionBehavior
in UIKit
. Adding them to an array of UIViews
leads to a memory leak. I put together a simple demo project that creates 10 animations of a group of views falling with gravity applied, and a collision with the enclosing view's bounds. (Code below.) The Leaks template in Instruments reports nine 64-byte leak for each run.
- (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;
}
}
I'd really like to be able to implement collisions in an app I'm working on, but this leak makes it unusable. I have tried saving the collisionBehavior in property and reusing it. That prevents leaking all but one 64-byte chunk of memory, but the collisions no longer work when that's done. Can anyone suggest a workaround that works?
I ran into the same issue but fixed the memory leak by setting the boundaries using UICollisionBehavior's
addBoundaryWithIdentifier
Unfortunately setting boundaries with translatesReferenceBoundsIntoBoundary
and setTranslatesReferenceBoundsIntoBoundaryWithInsets
caused leaks for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.