Зачем сохранять статическую переменную?

#objective-c #memory-management #retain #static-variables

#objective-c #управление памятью #сохранить #статические переменные

Вопрос:

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

Смотрите этот код: https://github.com/magicalpanda/MagicalRecord/blob/master/Source/Categories/NSManagedObjectContext MagicalRecord.m#L24-29

Ответ №1:

Я предполагаю, что вы имеете в виду указатель на статический объект, такой как static NSString *foobar; .

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

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

Комментарии:

1. Джонатан прав! Что, если переданный аргумент находится в пуле автоматического выпуска и будет автоматически выпущен сразу после вызова метода?! -> доступ к статическому указателю приведет к сбою (в основном, EXEC_BAD_ACCESS)

2. Мартин, небольшая поправка: это EXC_BAD_ACCESS (ИСКЛЮЧЕНИЕ как в exception).

Ответ №2:

Упрощенная версия принятого ответа Джонатана Гринспена:

retain Не для переменной, которая указывает на объект. Эта переменная будет существовать вечно, потому что она статична. retain Относится к объекту, на который указывает переменная. Без retain объект мог (и должен) быть освобожден. Тогда у вас есть переменная, указывающая на вещь, которая вызовет sigabrt . Эта переменная, указывающая в никуда, известна как «висячий указатель».

Для контекста ARC лучшее, что можно сделать, это объявить статическую переменную как strong , поэтому что-то вроде этого:

 static ThatClass * __strong thatStaticVariable;
  

Это гарантирует, что объект, на который thatStaticVariable указывает, будет действительным объектом (т. Е. Никогда не будет освобожден) после назначения. Однако на самом деле вам вообще не нужно ключевое слово __strong, потому что оно используется по умолчанию (так говорит документация, спасибо @zpasternack), поэтому просто используйте

 static ThatClass *thatStaticVariable;
  

и ты молодец.

Примечание: навсегда = во время работы приложения

Комментарии:

1. В ARC любой сохраняемый объект без явного квалификатора владения неявно __strong, так говорится в документах .