2010-03-23 2 views
1

Я видел подобную строку кода носятся в яблоках код:Утечка памяти с использованием (аннулируются) Alloc

(void)[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self]; 

URLRequest мой собственный пользовательский класс. Я не писал этого, и я думаю, что парень, который просто схватил его с примера Apple. Для меня это должно протекать, и когда я его тестирую, я уверен, что он протекает через 16 байт. Не так ли? Я знаю, как это исправить, если это так, но не было уверен, как это было взято из кода Apple.

EDIT: Проблема была с SDK, а не с указанным выше кодом. См. Ответ ниже для получения дополнительной информации.

+0

Я бы/не использовал/не использовал какой-либо код с методом, начинающимся с '-initializeSomething': любой, кто не знает достаточно Objective-C, чтобы назвать свой метод' -initSomething', скорее всего, не будет правильно избегать утечек: в то время как может звучать жестко, одна простая ошибка, подобная этой, может действительно показать незнакомость с набором инструментов. –

+1

:/Хотя у вас есть точка не в том, что выбор нит? У него может быть страстная ненависть к сокращению слов. Остальная часть его кода не течет либо – Rudiger

+0

Rudiger: Следующее правильное соглашение об именах - это/всегда/хорошая идея. –

ответ

3

Думал, что я мог бы это обновить, поскольку после дальнейших испытаний и выпуска iOS4 он изменился.

Приведенный выше код не течет, а объем памяти приложения возвращается в нормальное состояние даже после 200 итераций кода. Утечка произошла в iOS3, но была очень маленькой, в iOS4 она полностью исчезла как в симуляторе, так и в устройстве.

Некоторые могут задаться вопросом, почему вы хотели бы реализовать этот код, но он работает и имеет смысл при работе с множеством разных NSURLConnections во всем вашем коде, работающем одновременно.

2

Совершенно не уверен, что этот код должен выполнить. Кажется, что он нарушает каждое соглашение о методах инициализации. Какой смысл возвращать указатель void из метода инициализации? Вся цель метода инициализации - вернуть объект. Где вы видели это в примерах кода Apple?

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

Edit:

It basically does an NSURLConnection. Because we are submitting a lot of forms with a lot of different values we put it in an external class. All the delegate methods like didFailWithError: are in NSURLRequest and connectionDidFinishLoading just passes the data to its delegate. So it doesn't really need to return anything as it is done through a delegate method.

Да, вам нужно переделать это. В настоящее время этот метод является просто катастрофой, ожидающей своего появления. Если ничего другого, все остальные, смотрящие на этот код, будут совершенно смущены тем, что вы делаете.

Если у вас нет необходимости сохранять созданный объект, затем перемещайте его выделение и полностью очищайте внутри метода. Измените префикс имени метода с «initialize» на что-то вроде «setup», «configure», «purchase» и т. Д., Чтобы имя не подразумевало, что оно создает и возвращает и объект.

Если вам нужен экземпляр с одним выстрелом для определенного класса, используйте метод класса, например, предложенный Майклом Аароном Сафяном (опять же без инициализации имени). Метод класса должен инициализировать экземпляр внутри, выполнить необходимые операции, вернуть данные в любом месте, а затем исключить экземпляр.

Таким образом, вам не придется беспокоиться о утечках, и все, кто может читать ваш код (включая вас, месяцы в пути), сразу поймут, что делает код.

+0

В основном это NSURLConnection. Поскольку мы представляем множество форм с множеством разных значений, мы помещаем их в внешний класс. Все методы делегата, такие как didFailWithError: находятся в NSURLRequest, а connectionDidFinishLoading просто передает данные своему делегату. Поэтому на самом деле не нужно возвращать что-либо, как это делается с помощью метода делегата. – Rudiger

+0

Да. Мне потребовались годы, чтобы понять, и тогда парень показал мне демо-код Apple, откуда он его получил. Думаю, я мог бы отказаться от всего этого и начать все заново. – Rudiger

2

Да. Это утечка, которая может быть легко исправлена ​​путем добавления autorelease:

 
[[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self] autorelease]; 

Может быть, лучше исправить было бы создать функцию класса, что делает это:

 
@interface URLRequest 
{ 
    // ... 
} 
// ... 
+ (void) requestWithValues:/* ... */ 
// ... 
@end 

Тогда вы могли бы просто использовать [ URLRequest requestWithValues:/* ... * /] без вызова alloc.

+0

Я не могу назвать авторекламу, потому что NSURLConnection в URLRequest может ответить после цикла запуска. Я попробовал, и он падает. Я рассмотрю ваше другое исправление, хотя оно звучит лучше. – Rudiger

+0

@Rudiger, если вам нужно, чтобы экземпляр сохранялся, вы должны сохранить его как член объекта, который его использует, и использовать нормальный выпуск для члена в методе dealloc. –

+0

+1 Метод класса - это, безусловно, путь – TechZen

Смежные вопросы