Утечка памяти для decodeObjectForKey в пользовательском объекте - PullRequest
0 голосов
/ 06 декабря 2010

Я столкнулся с утечкой при попытке загрузить сохраненные пользовательские объекты из NSUserDefaults.Вот код, который является виновником.Кто-нибудь видит что-то явно неправильное?

@interface CustomQuery : NSObject <NSCoding> {
 NSString *theTitle;
 NSString *query;
}

@property(nonatomic, retain) NSString *theTitle;
@property(nonatomic, retain) NSString *query;

- (id)initWithCoder:(NSCoder *)aDecoder {

if (self = [super init]) {
    //tempTitle is leaking
    NSString *tempTitle = [[aDecoder decodeObjectForKey:@"QueryTitle"] retain];
    self.theTitle = tempTitle;
    [tempTitle release];

    //tempQuery is leaking
    NSString *tempQuery = [[aDecoder decodeObjectForKey:@"QueryValue"] retain];
    self.query = tempQuery;
    [tempQuery release];
}
return self;
}

- (void)dealloc {
 [theTitle release];
 [query release];
 [super dealloc];
}

Это также указывается как утечка в инструментах

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedQueries"];
if (dataRepresentingSavedArray != nil)
{

    //This is Leaking in Instruments
    NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
    if (oldSavedArray != nil) {

        //tempCustomQueryArray is also leaking
        NSMutableArray *tempCustomQueryArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
        if (savedQueries != nil) {
            savedQueries = nil;
        }
        self.savedQueries = tempCustomQueryArray;
        [tempCustomQueryArray release];
    }
 }

Ответы [ 2 ]

2 голосов
/ 06 декабря 2010

В этом:

NSString *tempTitle = [[aDecoder decodeObjectForKey:@"QueryTitle"] retain];
self.theTitle = tempTitle;
[tempTitle release];

retain и release не нужны, потому что ваша собственность будет retain объектом. Тем не менее, я думаю, что эти две струны - красная сельдь; вероятно, что утечка находится где-то еще.

Я подозреваю, что savedQueries не высвобождается в dealloc, который, как я предполагаю, не отображается. Это зависло бы от запросов и множества других вещей.

Это не совсем объясняет, откуда исходит утечка oldSavedArray (если я что-то упустил).

Включите отслеживание удержания / выпуска в инструменте распределения и посмотрите, где вызывается каждое удержание / разблокирование. Вы найдете где-нибудь неуравновешенный.

Я написал сообщение в блоге , которое связано и может быть полезным.

0 голосов
/ 06 декабря 2010

Я не вижу, где вы реализовали метод делегата encodeWithCoder или как вы архивируете (сохраняя в NSUserDefaults).Я также попытался бы изменить ваши методы CustomQuery.m для отражения:

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:self.theTitle forKey:@"QueryTitle"];
    [encoder encodeObject:self.query forKey:@"QueryValue"];
}

- (id)initWithCoder:(NSCoder *)aDecoder {

    self = [super init];
    self.theTitle = [aDecoder decodeObjectForKey:@"QueryTitle"];
    self.query = [aDecoder decodeObjectForKey:@"QueryValue"];

    return self;
}
...