AwakeFromNib vs didSet: где установить шрифт или радиус угла и почему?

Я пытаюсь понять разницу между установкой font на метку или cornerRadius на представление в didSet выхода UILabel или UIView и выполнением этого в awakeFromNib.

Какой из них является хорошей практикой и почему? Есть ли какая-либо причина, связанная с производительностью или компиляцией?

@IBOutlet weak var titleLabel: UILabel! {
   didSet {
      titleLabel.font = UIFont
   }
}

против

override func awakeFromNib() {
   super.awakeFromNib()
   // Initialization code
   titleLabel.font = UIFont
}

Поскольку метка представляет собой IBOutlet, лучше всего установить шрифт в Interface Builder. В любом случае didSet наблюдатель за торговой точкой бессмысленен. И awakeFromNib имеет смысл, только если выполняется другой Код инициализации. Если вам действительно нужно установить шрифт в коде, сделайте это в viewDidLoad.

vadian 21.03.2022 12:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
57
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Если вы просто устанавливаете простой шрифт:

titleLabel.font = UIFont(name: "SomeFamily", size: 20)

тогда на самом деле не имеет значения, делаете ли вы это в didSet или awakeFromNib. Однако, если ваш шрифт зависит от свойства какого-либо другого IBOutlet, например (надуманный пример здесь):

titleLabel.font = UIFont(name: anotherLabelOutlet.text!, size: 20)

Тогда вам обязательно стоит это сделать в awakeFromNib. В awakeFromNib как есть задокументировано:

When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.

Однако в didSet из titleLabel не обязательно верно, что anotherLabelOutlet было установлено. Розетки устанавливаются в негарантированном порядке.

Это относится не только к настройке шрифтов, но и к любой инициализации, в которой задействованы другие выходы.

С другой стороны, если где-то в конце строки вы встретите переназначатьtitleLabel (по какой-то странной причине), эта новая метка не получит установленный вами шрифт, если вы установите его в awakeFromNib, но получит, если вы установите его в didSet.

// in a later part of the code...
titleLabel = UILabel(frame: ...)
// titleLabel now has the new font if you set it in didSet, otherwise it won't

Я бы порекомендовал вам не думать об этом слишком много и просто сделать это в awakeFromNib, и вообще избегать переназначения IBOutlet.

Спасибо за разъяснение, люди борются за это в обзорах кода: D подумал, что я также должен получить совет от некоторых экспертов.

Sharad Chauhan 21.03.2022 13:10

@SharadChauhan На самом деле я забыл упомянуть, как говорится в комментарии Вадиана, лучше всего установить его в IB, но это не всегда возможно.

Sweeper 21.03.2022 13:13

@SharadChauhan Обратите внимание, что метод awakeFromNib не будет вызываться, если вы создадите свой объект программно.

Leo Dabus 21.03.2022 13:54

Ответ для хорошей практики:

Если функции компонента, который вы создадите, не зависят от другого компонента, использование didSet лучше с точки зрения читабельности кода, но я не думаю, что есть разница в производительности.

Если у вас слишком много компонентов, ввод свойств этих компонентов в awakefromnib может повлиять на читабельность кода.

Другие предоставили частичную информацию. Вот описание различных методов, которые вы упомянули (а также некоторые другие)

awakeFromNib() вызывается один раз после загрузки объекта "из архива пера". В современной iOS это обычно означает раскадровку, хотя вы по-прежнему можете загружать элементы пользовательского интерфейса из файлов XIB (современное название файлов пера). Этот метод не вызывается, если объект не загружается из архива пера.

didSet — это функция языка Swift, которая позволяет прикреплять код к свойству, которое запускается каждый раз при изменении этого свойства. Используйте код в замыкании didSet для кода, который вы хотите выполнять каждый раз, когда определенному свойству присваивается новое значение. Это большая разница в использовании этого метода: он вызывается только тогда, когда свойству, к которому он прикреплен, присваивается новое значение, и он будет называться каждый раз, когда свойство получает новое значение.

Метод viewDidLoad() — это метод, который вы можете реализовать в своих подклассах UIViewController, который вызывается один раз после загрузки иерархии представлений вашего контроллера представления. Этот метод является хорошим местом для настройки представления, которое невозможно выполнить в раскадровке. Эта функция должна быть реализована как метод экземпляра подкласса UIViewController.

Как уже говорили другие, если вы используете раскадровки, установка шрифта вашей метки в раскадровке, вероятно, является лучшим способом.

Если вы строите иерархию представлений вашего контроллера представления в коде, вы, вероятно, реализуете метод loadView() для создания и настройки представлений ваших контроллеров представлений. В этом случае имеет смысл установить их шрифт и другие свойства там.

Если вы используете SwiftUI, вы, скорее всего, настроите свои View в замыкании, которое вы передаете в их инициализатор.

Другие вопросы по теме