【问题标题】:XCode 4.6 shows a warning of memory leak for method + (void)beginAnimations:(NSString *)animationID context:(void *)context;XCode 4.6 显示方法 + (void)beginAnimations:(NSString *)animationID context:(void *)context; 的内存泄漏警告
【发布时间】:2013-02-13 07:32:47
【问题描述】:

Iphone - how to pass a parameter to animationDidStop? 此处的这个问题在上下文中提出了整个问题。根据那里的最佳答案,我在我的 animationDidStopSelector 中发布了上下文。但是自从我更新了我的 Xcode,我收到了这个警告

 - (void) helloThere: (int) myValue {

  // I am trying to pass myValue to animationDidStop
  [UIView beginAnimations:nil context:[[NSNumber alloc] initWithFloat:self.view.frame.origin.x]]; //Warning raised on this line
  [UIView setAnimationDuration:1.0];
  [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
  [UIView setAnimationDelegate:self];

  // do stuff
  [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {

  CGFloat usesThisValue = [(NSNumber *) context floatValue];
  [(NSNumber *) context release];
}

日志中的警告说:

warning: Potential leak of an object       [UIView beginAnimations:nil context:[[NSNumber alloc] initWithFloat:self.view.frame.origin.x]]; //Warning raised on this line
 1 warning generated.

有解决办法吗?如果没有,我该如何为我的项目关闭此警告?

【问题讨论】:

  • 信息不够!泄漏点在哪里?请显示更多代码和更多来自 clang/instruments 的输出。
  • 希望我现在能更好地解释这个问题。
  • 如果您使用CFNumberRef 而不是NSNumber*,它还会抱怨吗?
  • @Richard 再次创建 CFNumberRef 需要我有一个指向该值的指针。这样它就变得类似于 stackoverflow.com/a/2297483/1685709 中的“malloc 方法”。因此,将重新生成相同的警告。尽管由于我对 CFNumberRef 的工作不多,但我可能完全做错了。你能提供一个你想要提出的例子吗?
  • begin / commitAnimations 是 iOS4 之前的古老 API,您应该改用基于块的 UIView 动画方法。

标签: ios objective-c xcode memory-leaks


【解决方案1】:

问题是您在此调用中分配了一个 NSNumber。号码没有公布。尝试改变这个:

[UIView beginAnimations:nil context:[[NSNumber alloc] initWithFloat:self.view.frame.origin.x]];

编辑 Here is a link to a post about handling the (void *)context

因此,您需要一些方法来保留对您的 NSNumber 的引用,以便以后清理。

self.contextNumber = [[NSNumber alloc] initWithFloat:self.view.frame.origin.x];
[UIView beginAnimations:nil context:self.contextNumber]; 

并在你的 dealloc 中清理它

【讨论】:

  • -1 将autorelease 对象用作void * 是不安全的,因为我们无法保证它的生命周期。
  • (因为这个 'object' 在后面的回调中使用,我们不知道该对象是否被释放(几乎可以肯定)并且它的内存被重用。)
  • 感谢@Richard 的更正。你是对的,我只是在查看参数是如何传递的,而不是传递给它的对象。
  • @Jaybit 将上下文作为 nil 传递不是更聪明吗?您正在为可以被另一个属性访问的东西创建另一个属性。
  • 我从来不需要传递除 nil 以外的任何东西。我只是想解释一下泄漏和警告是关于什么的,以及如何用你提供的东西来解决它。
猜你喜欢
  • 2018-07-23
  • 2012-02-16
  • 1970-01-01
  • 2011-12-14
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多