Кажущаяся утечка памяти в FastEnumeration при наследовании от NSMutableDictionary - PullRequest
2 голосов
/ 21 марта 2012

У меня есть класс, который действует как подкласс NSMutableDictionary (в основном по делегированию), поскольку у нас есть несколько пользовательских интерфейсов, обернутых вокруг словаря. При запуске инструмента утечки ios он идентифицирует мой метод keyEnumerator как источник утечки объектов NSFastEnumerationEnumerator.

Вот мой метод keyEnumeration в качестве делегата для обернутого NSMutableDictionary.

- (NSEnumerator*) keyEnumerator {
    return [dictionary keyEnumerator];
}

Обратный след утечки всегда показывает перечислитель в качестве источника:

- (void) someMethod {
    for (NSString *key in myWrappedDictionary) { ... }
}

Вот типичный след:

calloc
class_createInstance
__CFAllocateObject2
-[__NSCFDictionary keyEnumerator]
-[WrappedDictionary keyEnumerator]
-[NSDictionary countByEnumerating...
-[SomeClass someMethod]

Я ищу обходной путь или ошибку в моей одной строке кода. Я использую ARC.

Пример класса показан ниже. Вызов [WrappedDictionary createLeaks] создаст 9 утечек.

@interface WrappedDictionary : NSMutableDictionary {
    NSMutableDictionary *dictionary;
}
- (id) init;
- (NSUInteger) count;
- (NSEnumerator*) keyEnumerator;
- (void)setObject:(id)anObject forKey:(id)key;
@end
@implementation WrappedDictionary
- (id) init  {
    dictionary = [NSMutableDictionary new];
    return self;
}
- (NSUInteger) count { return [dictionary count]; }
- (NSEnumerator*) keyEnumerator {
    return [dictionary keyEnumerator];
}
- (void)setObject: anObject forKey:key {
    [dictionary setObject:anObject forKey: key];
}
+ (void) createLeaks {
    for (int i=0; i < 10; i++) {
        WrappedDictionary *dict = [WrappedDictionary new];
        [dict setObject:@"1" forKey:@"1"];
        [dict setObject:@"2" forKey:@"2"];
        [dict setObject:@"3" forKey:@"3"];
        for (NSString *key in dict) {
            NSLog(@"key=%@",key);
        }
    }
}
@end

Ответы [ 2 ]

1 голос
/ 22 марта 2012

Я обнаружил простой обходной путь.

Если я изменю метод keyEnumerator с

- (NSEnumerator*) keyEnumerator {
    return [dictionary keyEnumerator];
}

на

- (NSEnumerator*) keyEnumerator {
    NSEnumerator *e = [dictionary keyEnumerator];
    return e;
}

, утечка исчезнет.Это все еще не имеет смысла для меня, но, по-видимому, заставляет компилятор корректно возвращать ARC возврат из словаря.

1 голос
/ 21 марта 2012

Помните, что инструмент утечки просто показывает, где выделен фрагмент памяти , выделенный .Это не означает, что точка распределения является источником утечки.Более вероятный источник утечки находится в someMethod, или в вызывающей стороне someMethod, особенно если вы поместите это в ivar и затем сохраните цикл для всего объекта.

...