В другом месте вашего кода происходит что-то еще, поскольку приведенный выше код не освобождает этот экземпляр MyCustomClass
. Вот несколько возможных причин, по которым экземпляр, на который ссылается _obj
, может быть освобожден:
_obj
получает значение nil
где-то еще; _obj
снова устанавливается (например, вы снова позвонили func
), и старый экземпляр будет освобожден; или MyClass
, родительский объект сам по себе освобождается.
Я бы предложил две вещи для диагностики происходящего:
Во-первых, я бы посоветовал добавить dealloc
методы к MyClass
и MyCustomClass
, чтобы вы могли видеть, когда они освобождены:
- (void)dealloc {
NSLog(@"%s", __FUNCTION__);
}
Если Вы все еще не можете определить, что происходит, я бы предложил использовать инструменты для отслеживания каждой ссылки на рассматриваемый объект.
Так, например, запустите профилировщик ( команда + i или «Продукт» («Профиль») и выберите инструмент «Утечки». Перед началом записи сеанса убедитесь, что для параметра «Параметры записи ...» для инструмента «Распределения» не установлено на «Отменить события для освобожденной памяти», но установлено в «Запись счетчиков ссылок»:
Теперь вы можете записывать свой сеанс профилирования. Лично я добавил инструмент «Точки интереса» и добавил указатель, где я создал этот MyClass
экземпляр,
- (void)viewDidLoad {
[super viewDidLoad];
os_log_t log = os_log_create("ViewController", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
os_signpost_id_t identifier = os_signpost_id_generate(log);
os_signpost_event_emit(log, identifier, "MyClass");
MyClass *myClass = [[MyClass alloc] init]; // the problem here is that I’m using a local variable for the parent class, but the situation in your case may vary
[myClass func];
}
Но если вы знаете, когда создается этот объект, вам может не потребоваться который. Но приятно видеть эти указатели в инструментах.
В любом случае, упражняйте свое приложение, чтобы вы могли проявить проблему. Затем остановите запись. Затем выберите инструмент «Распределение» и найдите свой объект:
Вы можете (нажав на стрелку рядом с вашим адресом для этого объекта) увидеть каждая ссылка добавлена и удалена:
Я не только вижу, что она была освобождена, но я вижу полный стек проследите, где это произошло. Обратите внимание, что метод func
находится не в этой трассировке стека, а, скорее, я был в viewDidLoad
, внутри dealloc
из MyClass
, который вызвал dealloc
из MyCustomClass
. Я даже могу дважды щелкнуть viewDidMethod
в моем стеке справа и быть взятым прямо там, где это произошло:
Теперь я вижу проблема в том, что я «случайно» сделал MyClass
локальной переменной. Поэтому я бы изменил его, чтобы использовать это свойство (которое в настоящее время закомментировано), и проблема исчезнет go.
Теперь точный источник проблемы в вашем случае, несомненно, будет меняться, но в зависимости от разумности dealloc
регистрация и возможность инструментов показывать нам все ссылки, которые были добавлены и удалены, вы сможете диагностировать проблему. И не забудьте go выполнить полную трассировку стека (сосредоточившись на вашем коде белым цветом) и посмотреть, все ли там имеет смысл. Часто мы будем останавливаться на рассматриваемом свойстве (obj
в вашем примере) и забывать смотреть на то, что происходит раньше в трассировке стека.