NSDictionary утечка памяти - PullRequest
0 голосов
/ 06 февраля 2012

У меня есть проблема с моим кодом, которую я не могу понять на всю жизнь, даже со всеми предыдущими темами здесь, на SO.Я извлекаю данные из источника JSON и помещаю их в NSDictionary, как указано в руководствах и в SO.При профилировании приложения я замечаю утечку памяти, вызванную этим NSDictionary, но освобождение его в конце этой функции приводит к сбою приложения.Какие-либо предложения?(Кстати: я новичок в Obj-C и программировании в целом, так что этот код в основном черпается из разных источников.)

- (void)fetchedData:(NSData *)responseData {
    //parse JSON for empty return
    if([responseData length] != 0){

        NSError* error = nil;
        //Convert JSON data to Obj-C
        NSDictionary* allShotData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

        NSString *player = [[allShotData objectForKey:@"player"] objectForKey:@"name"];
        NSString *shotDribbblePage = [allShotData objectForKey:@"url"];

        NSString *shotTitle = [allShotData objectForKey:@"title"];
        NSURL *imageURL = [NSURL URLWithString:[allShotData objectForKey:@"image_url"]];
        shotPageURL = [shotDribbblePage retain];


        //***********************
        //  Setup a-sync loading of shot
        //***********************

        NSOperationQueue *queue = [NSOperationQueue new];
        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage:) object:imageURL];   
        [queue addOperation:operation]; 
        [operation release];
        [queue release];
    }
    else{
        airballCount++;
        if (airballCount <= 20) {
            [self getDribbbleData];
        }
        else{
            NSLog(@"Too many airballs. Bailing out");
            [self showNoConnectionModal];
        }
    }
}

1 Ответ

2 голосов
/ 06 февраля 2012

Здесь:

shotPageURL = [shotDribbblePage retain];

вы, вероятно, должны использовать аксессор:

self.shotPageURL = shotDribbblePage;

Я должен действительно подчеркнуть, что вы должны использовать ваши аксессоры везде, так как они подсчитывают ваши рефери за вас (исключение: не в инициализаторах и в dealloc). Как отмечает Бериллий, вы можете подсчитать рефери вручную, если аксессора нет. Это принимает базовую форму:

[shotPageURL release];
shotPageURL = [shotDribbblePage retain];

Если происходит утечка содержимого возвращаемого словаря, то как вы использовали / ссылались на содержимое при чтении (чрезмерное сохранение).

Если вы используете свой класс в параллельном контексте, тогда вам обычно потребуется блокировка.

Если вы загружаете UIImage или иным образом взаимодействуете с объектами UIKit из вторичного потока - это нехорошо.

...