来自Analyzer的“不正确的减量”和“潜在泄漏”消息

时间:2011-10-26 03:41:39

标签: objective-c memory-management properties static-analysis

当我使用分析器编译时,我收到了一些消息。我声明了这些属性:

@property (nonatomic, retain) SyncServicePrimary *syncAndCartOne;
@property (nonatomic, retain) SyncServiceSecondary *syncAndCartTwo;

applicationDidBecomeActive调用此方法,我得到“分配对象的潜在泄漏”。

-(void)makeTheCartObjectsForCountry:(NSString*)country_key{
    self.syncAndCartOne = [[SyncServicePrimary alloc] init];
    self.syncAndCartTwo = [[SyncServiceSecondary alloc] init];
}

这在applicationWillResignActive中被调用;在这里,我得到“对象的引用计数的不正确的减少”。

-(void) removeTheCartObjects{
    [self.syncAndCartOne release];
    self.syncAndCartOne = Nil;    
    [self.syncAndCartTwo release];
    self.syncAndCartTwo = Nil; 
}

如果我将对象设置为autorelease,则错误消失,但我希望在应用程序隐藏时释放对象。

这是我正在做的事情,但这对于分析仪看到开始和结束来说太过分裂,或者这是我能做得更好/正确的事情所以它不会抱怨吗?

我很可能错过了关于releasealloc周期的简单概念(我来自PHP和C#)。

2 个答案:

答案 0 :(得分:4)

你的问题在这里:

-(void)makeTheCartObjectsForCountry:(NSString*)country_key{
    self.syncAndCartOne = [[SyncServicePrimary alloc] init];
    self.syncAndCartTwo = [[SyncServiceSecondary alloc] init];
}

您正在创建对象,然后保留它们(因为属性声明),因此当只有一个对象引用它们时,它们的引用计数为2。

你应该这样做:

-(void)makeTheCartObjectsForCountry:(NSString*)country_key{
    SyncServicePrimary *primary = [[SyncServicePrimary alloc] init];
    self.syncAndCartOne = primary;
    [primary release];

    SyncServiceSecondary *secondary = [[SyncServiceSecondary alloc] init];
    self.syncAndCartTwo = secondary;
    [secondary release];
}

答案 1 :(得分:2)

您已使用属性retain定义了属性,因此分析器假定属性的setter方法如下所示:

- (void)setSyncAndCartOne:(SyncServicePrimary *)newValue
{
    [newValue retain];
    [self->_syncAndCartOne release]; // access the instance variable holding the property value
    self->_syncAndCartOne = newValue;
}

如果您使用@synthesize,则setter方法将如下所示。

因此,当makeTheCartObjectsForCountry:返回时,syncAndCartOne中的对象的保留计数为2,但保留计数应为1.这就是使用autorelease修复它的原因。< / p>

出于同样的原因,您不应该[self.syncAndCartOne release]。当您将release分配给该属性时,setter方法将向旧对象发送nil