我正在尝试使用UISnapBehaviour为UIButton制作动画。我跟着Apple References和Apple Dynamics Catalog,但不是使用点击手势来启动动画,而是在视图启动时自动显示动画启动按钮。我的代码在模拟器中运行,即动画工作,动画结束时按钮也是如此。但即使动画看起来运行正常,Xcode中的Analyzer也会报告内存泄漏。
我尝试在动画仍然有效的几个地方重新定位[self.animator addBehavior:_snapButton];
和[self.animator removeBehavior:_snapButton];
,感觉就像我正确地做了一切。但无论我做什么,我都无法将保留计数设为0.我开始怀疑分析器中可能存在错误。
这是我的代码。我宣布了属性
@interface WaitView ()
@property (nonatomic, strong) UIDynamicAnimator *animator;
@property (nonatomic, strong) UISnapBehavior *snapBehavior;
@end
然后在UIDynamicAnimator
[super viewDidLoad]
- (void)viewDidLoad {
[super viewDidLoad]; // then tried [self startButton];
[self startButton]; // followed by [super viewDidLoad];
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator = animator;
[animator release];
} // Wait view
并在设置动画之前创建了一个UIButton
- (void)startButton {
CGPoint snapPoint = CGPointMake(160,284);
UIButton *wait = [UIButton buttonWithType:UIButtonTypeCustom];
wait.frame = CGRectMake(0, 0, 80, 80);
[wait setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"familyDot%d", 1]] forState:UIControlStateNormal];
wait.tag = 1;
[wait setTitle:[NSString stringWithFormat:@"%i", 1] forState:UIControlStateNormal];
[wait setTitleColor:[UIColor blackColor] forState: UIControlStateNormal];
wait.titleLabel.hidden = NO;
[wait addTarget:self action:@selector(tapTest) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:wait];
[self.animator removeAllBehaviors];
UISnapBehavior* _snapButton = [[UISnapBehavior alloc] initWithItem:wait snapToPoint:snapPoint];
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
[self.animator addBehavior:_snapButton];
[_snapButton release];
}
EDIT 根据Kurt的回复,解决方案是使用以下内容替换上面动画代码的最后五行
UISnapBehavior* _snapButton = [[[UISnapBehavior alloc] initWithItem:wait snapToPoint:target] autorelease];
self.animator = [[[UIDynamicAnimator alloc] initWithReferenceView:self.view] autorelease];
[self.animator addBehavior:_snapButton];
并包含按钮的测试。
- (void)tapTest {
NSLog(@“Start button works!");
}
以下是分析器报告的内存泄漏情况:
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
1。方法返回具有+1保留计数的Objective-C对象
[self.animator addBehavior:_snapButton];
2。泄漏的对象:此执行路径中未引用已分配的对象,并且保留计数为+1
有人可以告诉我这是否真的是内存泄漏?或者如果我做错了什么?
答案 0 :(得分:1)
是的,这会导致泄漏。问题全在一条线上:
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
[[UIDynamicAnimator alloc] initWithReferenceView:self.view]
返回一个带有+1引用计数的对象。当你完成它时,你有责任发布它。
然后你执行self.animator =
该对象。由于它是strong
属性,因此它会释放旧对象(如果有)并保留新对象。所以你的对象现在有+2保留计数。
然后从方法返回。假设您遵循通常的内存管理规则并稍后释放strong
属性,则只会释放一次该对象。它仍会有+1保留计数,你会泄漏它。
要解决此问题,请完全按照-viewDidLoad
中的操作执行操作:
UIDynamicAnimator *newAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator = newAnimator;
[newAnimator release];
或者:
self.animator = [[[UIDynamicAnimator alloc] initWithReferenceView:self.view] autorelease];
或转换为ARC!它会为你完成这一切。