首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个UISnapBehavior内存泄漏是虚惊吗?

这个UISnapBehavior内存泄漏是虚惊吗?
EN

Stack Overflow用户
提问于 2016-05-14 06:47:04
回答 1查看 93关注 0票数 0

我正在尝试用UIButton动画化UISnapBehaviour。我跟踪了苹果参考文献苹果动力目录,但是没有使用点击手势启动动画,而是在视图启动时自动显示一个动画开始按钮。我的代码在模拟器中运行,即动画工作,动画结束时按钮也是如此。但是,即使动画看起来工作得很好,Xcode中的分析器报告了内存泄漏。

我试着把[self.animator addBehavior:_snapButton];[self.animator removeBehavior:_snapButton];重新定位到动画还在工作的几个地方,感觉我做的一切都是正确的。但是,无论我做什么,我都不能将保留数取为0。我开始怀疑分析器里可能有个bug。

这是我的密码。我申报了财产

代码语言:javascript
复制
@interface WaitView ()
    @property (nonatomic, strong) UIDynamicAnimator *animator;
    @property (nonatomic, strong) UISnapBehavior *snapBehavior;
    @end

然后在UIDynamicAnimator之后初始化[super viewDidLoad]

代码语言:javascript
复制
- (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。

代码语言:javascript
复制
- (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];
}

根据Kurt的响应进行编辑,解决方案是用下面的代码替换我上面动画代码的最后五行

代码语言:javascript
复制
    UISnapBehavior* _snapButton = [[[UISnapBehavior alloc] initWithItem:wait snapToPoint:target] autorelease];
    self.animator = [[[UIDynamicAnimator alloc] initWithReferenceView:self.view] autorelease];
    [self.animator addBehavior:_snapButton];

还包括了按钮的测试。

代码语言:javascript
复制
- (void)tapTest {
    NSLog(@“Start button works!");
}

下面是分析器报告的内存泄漏的详细信息:

代码语言:javascript
复制
    self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; 

1.方法返回带有+1保留计数的object对象。

代码语言:javascript
复制
    [self.animator addBehavior:_snapButton];

2.对象泄漏:在此执行路径的后面不引用已分配的对象,其保留计数为+1

有人能告诉我这是否真的是内存泄漏吗?还是我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-16 00:16:36

是的,这会导致泄漏。问题就在一条线上:

代码语言:javascript
复制
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

[[UIDynamicAnimator alloc] initWithReferenceView:self.view]返回一个具有+1引用计数的对象。这是你的责任,释放它,当你完成它。

然后执行self.animator =该对象。因为它是一个strong属性,所以它释放旧对象(如果有的话)并保留新对象。所以你的对象现在有一个+2的保留计数。

然后从方法中返回。假设您遵循通常的内存管理规则并在稍后释放您的strong属性,那么您将只释放该对象一次。它仍然有一个+1保留计数,你会泄露它。

要修复它,请按照您在-viewDidLoad中所做的那样做

代码语言:javascript
复制
 UIDynamicAnimator *newAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
 self.animator = newAnimator;
 [newAnimator release];

或者:

代码语言:javascript
复制
 self.animator = [[[UIDynamicAnimator alloc] initWithReferenceView:self.view] autorelease];

或者转换成ARC!这一切都是为了你。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37223574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档