Что происходит, если я не сохраняю IBOutlet?

Это действительно связано с [1 115] HotSpot и значение по умолчанию значения опции ( опции Java HotSpot VM ), которые отличаются между конфигурацией клиента и сервера.

От Глава 2 технического описания ( архитектура Java HotSpot Механизма Производительности ):

JDK включает две разновидности VM - клиентское предложение и VM, настроенный для серверных приложений. Эти два решения совместно используют кодовую базу Java HotSpot среды выполнения, но используют различные компиляторы, которые подходят для отчетливо уникальных рабочих характеристик клиентов и серверов. Эти различия включают политику встраивания компиляции и значения по умолчанию "кучи".

, Хотя Сервер и Клиент VMs подобны, Сервер, VM был особенно настроен для максимизации пиковой рабочей скорости. Это предназначается для выполнения продолжительных серверных приложений, для которых нужна самая быстрая рабочая скорость больше, чем быстрое время запуска или меньший объем потребляемой памяти во время выполнения.

Клиент компилятор VM служит обновлением и для Классического VM и для своевременных (JIT) компиляторов, используемых предыдущими версиями JDK. Клиент VM предлагает улучшенную производительность времени выполнения для приложений и апплетов. Клиент Java HotSpot VM был особенно настроен для сокращения времени запуска приложения и объема потребляемой памяти, делая его особенно хорошо, подошел для клиентских сред. В целом клиентская система лучше для графический интерфейсов пользователя.

, Таким образом, реальная разница находится также на уровне компилятора:

Клиент компилятор VM не пытается выполнить многую из более сложной оптимизации, выполненной компилятором в Сервере VM, но в обмен, это требует, чтобы меньше времени проанализировало и скомпилировало часть кода. Это означает Клиент, который VM может запустить быстрее и требует меньшего объема потребляемой памяти.

Сервер VM содержит усовершенствованный адаптивный компилятор, который поддерживает многие из тех же типов оптимизации, выполненной путем оптимизации компиляторов C++, а также некоторой оптимизации, которая не может быть сделана традиционными компиляторами, такими как агрессивное встраивание через виртуальные вызовы метода. Это - конкурентоспособное преимущество и преимущество производительности перед статическими компиляторами. Адаптивная технология оптимизации очень гибка в своем подходе, и обычно превосходит даже усовершенствованные методы статического анализа и компиляции по характеристикам.

Примечание: выпуск [1 117] jdk6 обновляют 10 (см. Выпуск Обновления Notes:Changes в 1.6.0_10 ), пытался улучшить время запуска, но по различной причине, чем опции горячей точки, будучи упакованным по-другому с намного меньшим ядром.

G. Demecki указывает в комментариях , что в 64-разрядных версиях JDK, -client опция много лет игнорируется.
См. команда Windows java:

-client

Выбирает клиент Java HotSpot VM.
А 64-разрядный способный JDK в настоящее время игнорирует эту опцию и вместо этого использует сервер VM Горячей точки Java.

39
задан Jordan 9 August 2009 в 03:38
поделиться

4 ответа

Для ясности и согласованности рекомендуется объявлять свойства для всех ваших IBOutlets. Подробности подробно описаны в Руководстве по программированию управления памятью . Основная суть в том, что когда ваши объекты NIB разархивированы, код загрузки пера проходит и устанавливает все IBOutlets с помощью setValue: forKey :. Когда вы объявляете поведение управления памятью в свойстве, нет никакой загадки в том, что происходит. Если представление выгружается, но вы использовали свойство, которое было объявлено как сохранение, у вас все еще есть действительная ссылка на ваше текстовое поле.

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

Я собираюсь сделать некоторые предположения относительно контекста, в котором вы работаете - я предполагаю, что UITextField выше является подвидом другого представления, которое контролируется UIViewController. Я предполагаю, что в какой-то момент На этом этапе будет загружен файл пера, и все свойства IBOutlet будут установлены кодом загрузки пера с помощью setValue: forKey :. Здесь важно отметить представление верхнего уровня, для которого будет установлено свойство представления UIViewController (которое сохранит это представление верхнего уровня), и ваш UITextField, который также будет сохранен. Если он просто установлен, он будет сохранен кодом загрузки пера, в противном случае свойство сохранит его. UITextField также будет подпредставлением UIView верхнего уровня, поэтому он будет иметь дополнительное сохранение на нем, находясь в массиве subviews представления верхнего уровня, поэтому на этом этапе текстовое поле было сохранено дважды.

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

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

Поскольку UITextField был установлен как свойство, которое было сохранено, UITextField не освобождается, как это было бы, если бы он сохранил только массив subviews представления верхнего уровня.

Если бы вместо этого переменная экземпляра для UITextField не была установлена ​​через свойство, она также была бы рядом, потому что загрузка пера код сохранил его при установке переменной экземпляра.

Один интересный момент, который здесь подчеркивается, заключается в том, что, поскольку UITextField дополнительно сохраняется через свойство, вы, вероятно, не захотите сохранять его в случае предупреждения памяти. По этой причине вы должны обнулить свойство в методе - [UIViewController viewDidUnload]. Это позволит избавиться от последней версии в UITextField и освободить ее, как задумано. Если вы используете свойство, вы должны не забыть освободить его явно. Хотя эти два действия функционально эквивалентны, цель различна.

Если вместо замены текстового поля вы решили удалить его из представления, возможно, вы уже удалили его из иерархии представлений и установили для свойства значение nil или освободили текстовое поле. Хотя в этом случае можно написать правильную программу, легко допустить ошибку чрезмерного освобождения текстового поля в методе viewDidUnload. Чрезмерное освобождение объекта приводит к сбою; установка для свойства, которое уже имеет значение nil, снова равным nil, не является.

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

Также стоит отметить, что поведение управления памятью в Mac OS X на рабочем столе отличается. На рабочем столе установка IBOutlet без сеттера не сохраняет переменную экземпляра; но снова использует сеттер, если он есть.

71
ответ дан 27 November 2019 в 02:20
поделиться

Объявление чего-либо IBOutlet с точки зрения управления памятью ничего не делает (IBOutlet буквально # определяется как ничего). Единственная причина для включения IBOutlet в объявление - это если вы намереваетесь подключить его в Interface Builder (это то, для чего предназначено объявление IBOutlet, подсказка для IB).

Теперь единственная причина создать @property для переменной экземпляра - это если вы намереваетесь присвоить их программно. Если вы этого не сделаете (то есть вы только настраиваете свой пользовательский интерфейс в IB), не имеет значения, создаете ли вы свойство или нет. Нет причин, ИМО.

Вернемся к вашему вопросу. Если вы устанавливаете только этот ivar (usernameField) в IB, не беспокойтесь об этом свойстве, это ни на что не повлияет. Если вы ДЕЙСТВИТЕЛЬНО создаете свойство для usernameField (потому что вы создаете его программно),

11
ответ дан 27 November 2019 в 02:20
поделиться

Нет никакой разницы между тем, как работают эти два определения интерфейса, пока вы не начнете использовать средства доступа, предоставляемые свойством.

В обоих случаях вам все равно потребуется выпустить и установить в ноль IBOutlet в ваших методах dealloc или viewDidUnload.

IBOutlet указывает на объект, созданный в XIB-файле. Этот объект принадлежит объекту владельца файла XIB-файла (обычно это контроллер представления, в котором объявлен IBOutlet.

Поскольку объект создается в результате загрузки XIB, его счетчик сохранения равен 1 и принадлежит Владелец вашего файла, как упоминалось выше. Это означает, что владелец файла несет ответственность за его освобождение, когда он освобождается.

Добавление объявления свойства с атрибутом keep просто указывает, что метод установки должен сохранять переданный объект для установки - это правильный способ сделать это. Если вы не указали сохранение в объявлении свойства, IBOutlet может указывать на объект, который может больше не существовать из-за того, что он выпущен владельцем или автоматически выпущен в какой-то момент жизненного цикла программы. Его сохранение предотвращает освобождение объекта, пока вы не закончите с ним.

2
ответ дан 27 November 2019 в 02:20
поделиться

Well, in the second case you're adding a getter/setter method for that particular IBOutlet. Any time you add a getter/setter method you (almost always) want to have it set to retain for memory management issues. I think a better way to have posed you're question would have been this:

@interface RegisterController : UIViewController <UITextFieldDelegate>
{
IBOutlet UITextField *usernameField;
}
@property (nonatomic) IBOutlet UITextField *usernameField;

or

@interface RegisterController : UIViewController <UITextFieldDelegate>
{
IBOutlet UITextField *usernameField;
}
@property (nonatomic, retain) IBOutlet UITextField *usernameField;

In that case, then yes, you would need to add a retain since it will affect memory management. Even though it may not have any effects, if you're programatically adding and removing IBOutlet's, you could potentially run into issues.

As a general rule: always add an @property (with retain) whenever you have an IBOutlet.

0
ответ дан 27 November 2019 в 02:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: