2011-02-05 4 views
2

Сравните следующие 2 фрагменты:Этот код объектива-c вызывает утечку памяти?

образец 1:

[[UIApplication shareApplication] openURL: [NSURL URLWithString:@"http://stackoverflow.com"]] 

и образец 2:

NSURL *url = [[NSUrl URLWithString:@"http://stackoverflow.com"]; 
[[UIApplication shareApplication] openURL: url]; 
[url release]; 

ли образец 1 причина утечки памяти? есть [url release] в образце 2 избыточным?

Если утечка памяти происходит, насколько это плохо?

ответ

9

Образец 1 не вызывает утечки памяти и является общим способом его выполнения. Объект NSURL автореализован, и поэтому вы не должны выпускать его самостоятельно (как в примере 2).

-2

@BoltClock, я думаю, что вы не совсем правильно говорить, что объект autoreleased в образце 1.

В образце 2, переменная с именем url присваивается объект, возвращаемый из метода [NSUrl URLWithString:], тем самым увеличивая ИТС сохранить счет на 1. Чтобы сбалансировать это, нам нужно release. Хотя в примере 1 ссылка на объект напрямую передается получателю, и нам не о чем беспокоиться о его счету сохранения, следовательно, нет освобождения.

Обратите внимание, что мы не автореализуем, так как мы не сохранили ничего в первую очередь. «В коде, который автореализован, нет никакой переменной!»

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

+1

Извините, но это неправильно. Вы не должны выпускать объект, если вы его не создали, используя метод, который начинается с «alloc» или «new» или метода, который содержит «копию». URLWithString: возвращает автореализованный NSURL, который автоматически будет освобожден в конце runloop. [Руководство по программированию управления памятью] (http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/MemoryMgmt.html) –

+0

Согласовано с первой частью. И если URLWithString возвращает объект с автореализацией, то '[url release]' в образце 2 IS избыточно, не так ли? – Sailesh

+1

Вы ошибаетесь. Объект автореализован классом NSURL. Когда вы вызываете строку + (NSURL *) URLWithString: (NSString *), класс NSURL allocs-init создает новый экземпляр, затем автоматически передает и возвращает его вам. Если вы не сохраните его, вам не гарантировано, что он не будет выпущен во время жизни приложения (вероятно, он будет выпущен во время следующего цикла цикла). Если NSURL не выпустил экземпляр, вы создадите утечку, поскольку по соглашению вы являетесь владельцем объекта, только если его метод «конструктор» начинается с «init» или «copy». – viggio24

2

Образец 1 идеально подходит, как уже было описано выше. Однако образец 2 должен фактически привести к сбою. -URLWithString: является автореализованным, поэтому его количество удержания фактически уже будет равным нулю при сливе следующего пула авторезистов. Если вы освобождаете его явно, как вы делаете, это немедленно приведет к тому, что его значение останется в 0, что приведет к освобождению. Затем, когда пул авторесурсов сливается, он попытается снова освободить эту строку, в результате чего произойдет сбой.

Всегда лучше использовать команду «Сборка и анализ» в Xcode. Он может подобрать и предупредить вас о почти всех проблемах с утечкой памяти, хотя это не идеально. Тем не менее, это хорошая практика.

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