静态分析仪显示错误泄漏? (XCode 4.0、iOS 4.3 及更高版本)
祝大家十一月快乐,
我在我的项目上尝试了 Xcode Build 和分析,它显示了一些不寻常的泄漏,以我对 Objective C 的了解,我无法完全接受这些泄漏。
所以我决定建立一个测试项目并在这里询问。 .
MemoryTestController.h
@interface MemoryTestController : UIViewController{
UIImageView *tstImageView;
}
@property(nonatomic,retain) UIImageView *tstImageView;
@end
MemoryTestController.m
@implementation MemoryTestController
@synthesize tstImageView;
- (void)viewDidLoad{
[super viewDidLoad];
self.tstImageView = [[UIImageView alloc] //<==This object is leaking
initWithFrame:<SomeFrame>];
self.tstImageView.image = [UIImage imageNamed:@"SomeImage.png"];
[self.view addSubview:tstImageView];
[tstImageView release];
}
-(void)dealloc{
[tstImageView release];
[super dealloc];
}
@end
当我尝试构建和分析时,clang 静态分析器说
第 xx 行对象可能泄漏
罪魁祸首是
self.tstImageView = [[UIImageView alloc]initWithFrame:<SomeFrame>];
我认为每次分配/保留时都会释放一次。我是否遗漏了什么,或者静态分析器有一些错误?
编辑:那里有泄漏吗?
好吧,我使用仪器中的 Leak 工具运行上述项目。尽管我尝试了很多次,但它没有显示任何泄漏。我应该相信谁?静态分析仪还是泄漏仪?
Happy November to all,
Well I tried Xcode Build and analyze on my project, and it showed some unusual leaks, which I couldn't quite accept with my knowledge of Objective C.
So I decided to put up a test project and ask here..
MemoryTestController.h
@interface MemoryTestController : UIViewController{
UIImageView *tstImageView;
}
@property(nonatomic,retain) UIImageView *tstImageView;
@end
MemoryTestController.m
@implementation MemoryTestController
@synthesize tstImageView;
- (void)viewDidLoad{
[super viewDidLoad];
self.tstImageView = [[UIImageView alloc] //<==This object is leaking
initWithFrame:<SomeFrame>];
self.tstImageView.image = [UIImage imageNamed:@"SomeImage.png"];
[self.view addSubview:tstImageView];
[tstImageView release];
}
-(void)dealloc{
[tstImageView release];
[super dealloc];
}
@end
When I try Build and analyze, clang static analyzer say
Potential leak of an object at line xx
And the culprit line is
self.tstImageView = [[UIImageView alloc]initWithFrame:<SomeFrame>];
I think I am releasing once for every time I am allocing/retaining. Am I missing something, or Static analyzer has some bugs?
EDIT : Is there any leak there?
Well I run the above project using Leak tool in instrument..It didn't show any leak even though I tried many times..Whom should I believe? Static analyzer or Leak instrument?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的问题是你如何释放它:
你应该这样做:
检查器是正确的,因为它不能假设该变量与你设置的变量相同。因此,您在 OP 中使用的形式可能会引入引用计数不平衡,因为当您在 ivar 上发布消息时,ivar 的值可能不是您分配给它的值。
这些情况对于 UIImageView 来说不太可能,在您的程序上下文中也不太可能,但这些示例应该让您了解为什么检查器假设 object->ivar 关联不应该是可信:
在创建图像视图和通过 ivar 释放它的消息之间,您可以:
1)通过 setter 分配图像视图
2)通过getter访问图像视图
3)直接访问ivar,当添加到self.view时
最简单的例子是:
self
查看您通过的。在这种情况下,您传递的变量视图将泄漏,并且替换它的视图将出现负不平衡。这些都不可能在您的示例中发生,但它确实发生在现实世界的程序中,并且检查器根据位置而不是属性正确评估(检查器无法假设发生的大部分情况在方法调用内)。在这种情况下,它还鼓励一种良好的惯用风格。
静态分析器表示存在潜在泄漏,因为它无法保证其遵循的引用/分配被正确保留/释放。您可以通过将程序更改为看起来像我在示例中编写的那样来保证引用计数正确并取悦静态分析器。
您编写的方式使分析器无法遵循参考文献。
如果没有泄漏,也没有僵尸,那么就不存在泄漏。但解决方案很容易解决——而且程序在开发过程中会发生变化。使用我发布的表格要容易得多,因此工具集和您验证程序是否正确都更容易。静态分析器并不总是正确的,但是您应该调整您的程序以使其满意,因为静态分析非常有用。我发布的程序也更容易让人理解并确认它是正确的。
your problem is how you release it:
you should do it this way:
The checker is correct because it cannot assume that the variable is identical to the one you set. Therefore, the form you use in the OP could introduce a reference count imbalance because the ivar's value may not be what you assigned to it by the time you message release upon the ivar.
These cases are not likely for a
UIImageView
, and quite unlikely in the context of your program, but these examples should give you an idea as to why the checker assumes that object->ivar associations shall not be trusted:Between creation of the image view and the message to release it via the ivar, you have:
1) assignment of the image view via the setter
2) access of the image view via the getter
3) direct access of the ivar, when adding to self.view
UIImageView
is a bad example, but the checker does not know how types are generally passed around - even if it did, it would (at times) make unsafe assumptions.the simplest example would be:
self
in the process/effect of adding the subview, and replacing or removing the image view you passed. In that case, the variable view you passed would leak and the view it replaced it with would have a negative imbalance.Neither of those are likely to happen in your example, but it does happen in real world programs, and the checker is correctly evaluating based on locality, not property (the checker can't assume much of what happens inside a method call). It also encourages one good idiomatic style in this case.
The static analyzer says there is a potential leak because it is unable to guarantee the reference/allocation it follows is correctly retained/released. You can guarantee that reference counting is correct and please the static analyzer by changing you program to look like I wrote it in my example.
The way you have written it has made it impossible for the analyzer to follow the reference.
If you have no leaks and no zombies, then there is not a leak. But the solution is easy to fix - and programs have a way of changing during development. It's much easier to use the form I posted so it is easier for the toolset and for you to verify the program is correct. The static analyzer is not always correct, but you should adjust your programs to please it because static analysis is very useful. The program I posted is also easier for a human to understand and confirm that it is correct.
当您像这样使用保留声明属性时,
会添加一个设置器,当您分配给该属性时,该设置器将增加保留计数。当您执行以下操作时,您创建的对象已经有一个retainCount == 1,
因此tstImageView对象的retainCount中有2。
然后这样做
,尽管与释放时的泄漏无关,但像这样写,
因为设置器将正确设置保留计数
when you declare a property with retain like this
a setter is added that will incr the retainCount when you assign to the property. When you do as below the object you created has already a retainCount == 1
so the tstImageView object has 2 in retainCount.
do instead
then, although unrelated to your leak when you release it write like this instead
since the setter will then will properly set the retainCount