Проблема с анализатором: потенциальная утечка объекта, выделенного в строке 25 и сохраненного в oneCopy - PullRequest
0 голосов
/ 10 ноября 2011

Я обновил 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 ]

1 голос
/ 10 ноября 2011

Обращаясь сначала ко второму вопросу, вместо [[NSMutableDictionary alloc] initWithCapacity:[self count]] вы можете использовать [NSMutableDictionary dictionaryWithCapacity:[self count]], который вернет автоматически выпущенный объект, и вам придется сохранить его самостоятельно в вызывающем коде.

С другой стороны, вы можете переименовать ваш метод, чтобы начать со слова copy, если вы хотите, чтобы он возвращал сохраненный объект, а не выдавать ошибки - , что я думаю, именно то, что вы хотите сделать в этом случае . Остальная часть моего ответа предполагает, что вы выбрали этот путь.

Мой первоначальный ответ был следующим: вы не выпускаете oneCopy в конце каждой итерации. Попробуйте добавить [oneCopy release]; сразу после [ret setValue:oneCopy forKey:key];.

Однако, как указывает Александр Акерс , компилятор считает, что -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
0 голосов
/ 10 ноября 2011

Здесь есть две проблемы.Во-первых, как говорит @David Brainer-Banker, вам нужно освобождать oneCopy в конце каждой итерации, помещая [oneCopy release]; after you set [ret setValue: oneCopy forKey: key]; `.

Неправильный счетчик ссылокдекремент - вторая проблема.Это связано с тем, что объект oneCopy может иметь счетчик ссылок +1 или 0.Объекты, возвращаемые -copy и -mutableCopy, имеют refcount +1, но объект, возвращаемый -deepMutableCopy, имеет refcount 0, потому что его нет в new, copy или * 1015.* (и др.) семейства.

Этот вопрос является точной копией этого и имеет несколько отличных ответов.

...