2009-10-08 4 views
0

Привет всем, у меня проблемы с утечкой памяти. все от моего сохранить подсчет = 0, когда я dealloc их, но до сих пор я маркировки до утечки из следующего фрагмента кода:Проблемы с утечкой памяти

- (GKSession *) peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type { 
inSession = [[GKSession alloc] initWithSessionID:gameSessionID displayName:nil sessionMode:GKSessionModePeer]; 
printf("insession alloc on Start: %i\n", [inSession retainCount]); 
return inSession; 

}

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

- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker { 
picker.delegate = nil; 
mpicker.delegate = nil; 
inSession.delegate = nil; 
gameSession.delegate = nil; 

if(inSession != nil) { 

    [self invalidateSession:inSession]; 
    [inSession release]; 
    inSession = nil; 

} 

[picker release]; 

picker = nil; 
mpicker = nil; 



[inSession release]; 


if(self.gameSession != nil) { 
    [self invalidateSession:self.gameSession]; 
    [self.gameSession release]; 
    self.gameSession = nil; 
} 

[self.gameSession release]; 
self.gameLabel.hidden = NO; 
self.gameState = pongStateStartGame; 


[gameSession release]; 
[inSession release]; 

[inSession dealloc]; 
[gameSession dealloc]; 



[mpicker dealloc]; 

}

Где-код утечки и я не могу понять, за жизнь мне, где. Любая помощь с этим была бы удивительно оценена.

+0

Я удивлен, что этот код работает вообще ... есть возможность освободить inSession 3 раза с окончательным dealloc. Метод выпуска NSObject будет отменен, как только счет сохранения будет равен 0. Ваш делегат возвращает GKSession с ссылкой на владельца (+1). Я предполагаю, что класс, получающий GKSession от этого делегата, не освобождает ранее созданный GKSession. Поэтому, когда peerPickerController: sessionForConnectionType: вызывается снова, он вернет другой GKSession и потеряет отслеживание вашей предыдущей GKSession - утечки памяти. – pxl

ответ

3

Используйте Instruments, чтобы найти утечки.

Проблема в том, что вы еще не поняли Cocoa's memory management.

[inSession dealloc]; 
[gameSession dealloc]; 
[mpicker dealloc]; 

Вы должны никогда должны вызвать -dealloc себя. NSObject называет это, когда счетчик ссылок достигает 0.

Попробуйте узнать правильный способ управления памятью.

2

Рассмотрите возможность сборки и анализа Xcode 3.2 (в меню «Построение»). Это может быть очень полезно при поиске ссылок на подсчеты.

Если это не помогает, запустите инструмент «Утечки» в «Инструменты» («Run-> Run With Performance Tool-> Leaks»).

0

Попытка освободить его второй раз после установки указателя переменной на нуль не поможет - ничего не будет сделано. Также не вызывайте dealloc. Хотя технически не противоречит закону ваш метод

- (GKSession *) peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type

указывает scrappyness стиля, что может привести к такого рода утечки. Он создает новую GKSession и устанавливает ее в переменную экземпляра и возвращает ссылку на нее. Он не использует ни один из аргументов. Либо создайте переменную экземпляра ИЛИ, либо автоматически зарегистрируйте ее, и верните ее. Где код, вызывающий этот метод? Возвращает ли вызывающий абонент возвращаемое значение?

+0

использовали инструменты, и в инструментах он появляется. Использовали сборку и анализ, и ничего не появляется, нет никаких намеков на что-либо. Кроме того, все значения удержания достигли 0, поэтому я поставил dealloc для того, чтобы это произошло. все еще есть ошибка, когда приборы проверяют другую утечку. –

+0

вы все равно должны его убрать. Установите свойство inSession для сохранения тогда - (GKSession *) sessionForConnectionType: (GKPeerPickerConnectionType) тип { \t return [[GKSession alloc] initWithSessionID: gameSessionID displayName: nil] autorelease]; } // присвоить self.inSession = [whichObject? sessionForConnectionType: тип]; - - // релиз self.inSession = nil; У вас есть зомби? – 2009-10-08 16:55:36

+0

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

0

В этом втором разряде кода вы [inSession release] дважды, а THEN dealloc.

Извините, но это всего лишь 200 различных типов неправильных.

Никогда не звоните dealloc Система делает это за вас.

Не вызывайте release на том же объекте дважды в том же методе. Вы никогда не знаете, существует ли объект после первого вызова. Я удивлен, что вы не получаете исключений из-за освобождения, без всякой утечки.

Для быстрого объяснения использования удержания и отпускания см. Это question.

Для более подробного объяснения (и очень полезно) ознакомьтесь с документом Cocoa по этому вопросу.

+0

Я понимаю принцип счета за сохранением и выпуском, поэтому меня сейчас так запутывает, и я в отчаянии. Почему, если число равно 0, для всего, что я использую, это инструменты, обнаруживающие утечку с помощью inSession. или более, оригинальный код яблока, который никогда не позволял пользователю вручную выпускать переменную. –

0

Просто комментарий об использовании [x retainCount] для «помощи» в определении проблем памяти. Поскольку я узнал и пробовал это несколько раз - это НЕ МОЖЕТ отражать правильную ситуацию. Поэтому не полагайтесь на это значение - не используйте это - это, скорее всего, вызовет путаницу.

Во-вторых, это происходит со мной все время, когда я использую код Apple (который, конечно, работает в этом примере), а затем «из синего», он вызывает проблемы в моем коде (отображается в инструменте LEAKS) - без конечно, «злоупотреблял». Иногда я часами работаю и нахожу самые странные причины для странного поведения. Например, просто добавив UINavigationControllerDelegate в качестве протокола для ответа, код может внезапно протекать - без изменения какой-либо другой строки кода!