分析器问题:在第25行分配的对象的潜在泄漏并存储到'oneCopy'中

时间:2011-11-09 22:01:45

标签: objective-c xcode cocoa-touch analyzer

我已经升级了Xcode并且已经提供了大量的分析器警告:

  

第25行分配的对象的潜在泄漏并存储在'oneCopy'

有人能指出我正确的方向吗?

@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)mutableDeepCopy
{
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
    }
    return ret;
}
@end

屏幕截图显示行号:
enter image description here

#import "NSDictionary-DeepMutableCopy.h"


@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)mutableDeepCopy
{
    //NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSMutableDictionary *ret = [NSMutableDictionary dictionaryWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
        [oneCopy release];
    }
    return ret;

}
@end

2 个答案:

答案 0 :(得分:1)

首先解决您的第二个问题,而不是[[NSMutableDictionary alloc] initWithCapacity:[self count]]您可以使用[NSMutableDictionary dictionaryWithCapacity:[self count]]来返回自动释放的对象,您必须自己将其保留在调用代码中。

另一方面,你可以将你的方法重命名为单词copy,如果你想让它返回一个保留的对象而不是抛出错误 - 我认为这正是你想要做的事情< / strong>即可。我的回答的其余部分假定您采取了这条道路。

我原来的答案如下:你没有在每次迭代结束时释放oneCopy。请尝试在[oneCopy release];之后添加[ret setValue:oneCopy forKey:key];

但是,作为Alexsander Akers points out编译器认为-mutableDeepCopy具有0引用计数。因此,如果您按照上面的建议重命名并按照我最初建议的那样包含[oneCopy release],那么它应该解决这两个问题。如果没有,请务必查看他引用的问题中的其他一些解决方案。

示例:

@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)copyWithDeepCopiedValues
{
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];

    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue copyWithDeepCopiedValues];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setObject:oneCopy forKey:key];

        [oneCopy release];
    }

    return ret;
}
@end

答案 1 :(得分:0)

这里有两个问题。首先,正如@David Brainer-Banker所说,你需要在每次迭代结束时释放oneCopy [oneCopy release]; after you set [ret setValue:oneCopy forKey:key];`。

错误的引用计数减少是第二个问题。这是因为oneCopy对象可能具有+10引用计数。 -copy-mutableCopy返回的对象具有+1引用计数,但-deepMutableCopy返回的对象具有0引用计数,因为它不在new中{1}},copycreate(等)家庭。

这个问题与this one完全相同,并且有一些很好的回应。