Kri*_*dra 2 iphone memory-leaks objective-c clang-static-analyzer ios
祝大家十一月快乐,
好吧,我尝试了Xcode Build并对我的项目进行了分析,并且它显示了一些不寻常的泄漏,我对Objective C的了解无法接受.
所以我决定提出一个测试项目并在这里问...
@interface MemoryTestController : UIViewController{
UIImageView *tstImageView;
}
@property(nonatomic,retain) UIImageView *tstImageView;
@end
Run Code Online (Sandbox Code Playgroud)
@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
Run Code Online (Sandbox Code Playgroud)
当我尝试构建和分析时,clang静态分析器说
线xx处的物体可能泄漏
罪魁祸首是
self.tstImageView = [[UIImageView alloc]initWithFrame:<SomeFrame>];
Run Code Online (Sandbox Code Playgroud)
我想我每次分配/保留时都会释放一次.我错过了什么,或静态分析器有一些错误?
好吧,我使用仪器中的泄漏工具运行上述项目.即使我多次尝试也没有显示任何泄漏......我应该相信吗?静态分析仪或泄漏仪器?
你的问题是你如何释放它:
- (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]; // << here
}
Run Code Online (Sandbox Code Playgroud)
你应该这样做:
- (void)viewDidLoad{
[super viewDidLoad];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:<SomeFrame>];
imageView.image = [UIImage imageNamed:@"SomeImage.png"];
self.tstImageView = imageView;
[imageView release];
[self.view addSubview:self.tstImageView];
}
Run Code Online (Sandbox Code Playgroud)
检查器是正确的,因为它不能假设变量与您设置的变量相同.因此,您在OP中使用的表单可能会引入引用计数不平衡,因为ivar的值可能不是您在ivar上发布消息时分配给它的值.
UIImageView在程序的上下文中,这些情况不太可能,并且不太可能,但这些示例应该让您了解为什么检查程序假定object-> ivar关联不受信任:
在创建图像视图和通过ivar释放它的消息之间,您有:
self.tstImageView = [[UIImageView alloc] initWithFrame:<SomeFrame>];
self.tstImageView.image = [UIImage imageNamed:@"SomeImage.png"];
[self.view addSubview:tstImageView];
Run Code Online (Sandbox Code Playgroud)
1)通过设置器分配图像视图2)通过吸气剂访问图像视图3)在添加到self.view时直接访问ivar
UIImageView这是一个不好的例子,但是检查器不知道类型通常如何传递 - 即使它确实如此,它(有时)会做出不安全的假设.最简单的例子是:
- (void)setName:(NSString *)inName {
NSString * prev = name;
if (inName == prev) return;
if (0 == [inName count]) name = @"";
else name = [inName copy];
[prev release];
}
Run Code Online (Sandbox Code Playgroud)
self添加子视图的过程/效果,并替换或删除您传递的图像视图.在这种情况下,您传递的变量视图将泄漏,并且替换它的视图将具有负不平衡.这些都不可能在你的例子中发生,但它确实发生在现实世界的程序中,并且检查器正在基于局部性而不是属性正确评估(检查器不能假设在方法调用内发生的事情).在这种情况下,它也鼓励一种好的惯用风格.
编辑:那里有泄漏吗?
好吧,我使用仪器中的泄漏工具运行上述项目.即使我尝试了很多次也没有显示任何泄漏......我应该相信吗?静态分析仪或泄漏仪器?
静态分析器表示存在潜在泄漏,因为它无法保证正确保留/释放其遵循的参考/分配.您可以保证引用计数是正确的,并通过将程序更改为我在我的示例中编写的程序来取悦静态分析器.
您编写它的方式使分析仪无法遵循参考.
如果你没有泄漏而没有僵尸,那么就没有泄漏.但是解决方案很容易解决 - 程序在开发过程中有改变的方法.使用我发布的表单要容易得多,因此工具集更容易验证程序是否正确.静态分析仪并不总是正确的,但您应该调整程序以取悦它,因为静态分析非常有用.我发布的程序也更容易让人理解并确认它是正确的.