Anonymous Quiz
    27%
    Методика для прерывания выполнения функции, если значение `nil`
      
    25%
    Способ вызова свойства, метода или субскрипта на `nil` без вызова ошибки
      
    45%
    Последовательность условных операторов для проверки `nil`
      
    3%
    Техника для уменьшения использования памяти при работе с переменными
      
    Когда работаешь с замыканиями или опциональными типами, часто встречаешься с понятиями "weak" и "unowned". Оба этих ключевых слова используются для предотвращения утечек памяти в случае циклических ссылок, но между ними есть важные различия.
nil, когда объект, на который она указывает, уничтожается. Это полезно, когда объект может быть уничтожен в любой момент, и вы хотите избежать висячих указателей.class ExampleClass {
    var property: AnotherClass?
}
class AnotherClass {
    weak var backReference: ExampleClass?
}class ExampleClass {
    var property: AnotherClass?
}
class AnotherClass {
    unowned var backReference: ExampleClass
}Главное различие заключается в том, что "weak" ссылки всегда являются опциональными и автоматически становятся
nil, когда объект удаляется, предотвращая висячие указатели. "Unowned" ссылки предполагают, что другой объект будет жить столько же или дольше, и поэтому они не являются опциональными и не обнуляются.Важно понимать эти различия, чтобы избежать ошибок времени выполнения, особенно при работе с несильными ссылками, так как обращение к уже освобожденному объекту через несильную ссылку приведет к крашу программы.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤1👍1
  Anonymous Quiz
    47%
    sort()
      
    49%
    sorted()
      
    3%
    order()
      
    0%
    arrange()
      
    🤔3
  Ассоциированный тип — это особенность протоколов, позволяющая определить плейсхолдер для типа, который будет уточнён только тогда, когда протокол будет принят каким-либо типом. Это предоставляет дополнительный уровень гибкости в определении и использовании протоколов, позволяя создавать обобщённые протоколы, которые могут быть адаптированы для работы с любыми типами.
С помощью ассоциированных типов протоколы могут быть написаны таким образом, чтобы они были не конкретно привязаны к какому-либо типу. Это делает протоколы очень мощным инструментом для создания гибких и повторно используемых компонентов.
protocol Container {
    associatedtype Item // Определение ассоциированного типа
    
    mutating func append(_ item: Item)
    var count: Int { get }
    subscript(i: Int) -> Item { get }
}
struct IntStack: Container {
    // конкретная реализация ассоциированного типа Item как Int
    typealias Item = Int
    // реализация требований протокола
    var items = [Item]()
    mutating func append(_ item: Item) {
        items.append(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Item {
        return items[i]
    }
}В этом примере, протокол
Container определяет требования для контейнерных типов, включая ассоциированный тип Item. Когда структура IntStack принимает протокол Container, она указывает, что ассоциированный тип Item будет представлен как Int. Это позволяет протоколу Container быть адаптивным и работать с любыми типами, сохраняя при этом строгую типизацию и безопасность типов, характерные для Swift.Ассоциированные типы особенно полезны в контексте обобщённого программирования, где один и тот же протокол может быть использован для определения функциональности, применимой к широкому спектру типов, без привязки к конкретным типам данных в самом протоколе.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤2
  Anonymous Quiz
    73%
    ["key1": "value1", "key2": "value2"]
      
    17%
    Dictionary("key1": "value1", "key2": "value2")
      
    4%
    {["key1": "value1", "key2": "value2"]}
      
    5%
    (key1: "value1", key2: "value2")
      
    В ООП существует множество паттернов, которые помогают решать различные задачи проектирования и разработки ПО. Паттерны проектирования представляют собой проверенные решения типовых проблем, с которыми сталкиваются разработчики. Они способствуют написанию более чистого, понятного и масштабируемого кода. Основные категории паттернов включают в себя порождающие, структурные и поведенческие паттерны.
Порождающие паттерны
Эти паттерны связаны с процессами создания объектов, делая систему независимой от способа создания, компоновки и представления объектов.
Структурные паттерны описывают, как объединять объекты и классы в более крупные структуры.
Поведенческие паттерны регулируют эффективное взаимодействие и распределение обязанностей между объектами.
Эти паттерны не только помогают решать типичные задачи проектирования, но и способствуют созданию более читаемого, удобного для поддержки и масштабируемого кода.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤1
  Anonymous Quiz
    5%
    `?`
      
    94%
    `!`
      
    0%
    `*`
      
    0%
    `&`
      
    Механизм Copy-on-Write (CoW) используется для оптимизации производительности и использования памяти при копировании объектов. Этот механизм особенно полезен для неизменяемых (immutable) структур данных. CoW часто ассоциируется со стандартными коллекциями и собственными типами данных, реализованными как структуры (value types), такие как
Array, String, Dictionary, и Set.Работает так, что копия объекта создаётся только в тот момент, когда происходит попытка модификации. До этого момента все копии объекта фактически ссылаются на одни и те же данные в памяти. Это позволяет сэкономить как время, так и память, поскольку избегается ненужное дублирование данных, когда оно не требуется.
Автоматически применяет механизм CoW к своим стандартным коллекциям, таким как
Array, String, Dictionary, и Set. Это означает, что при передаче этих объектов в функции или при их копировании реальное дублирование данных происходит только в случае модификации одной из копий. Таким образом, если вы создаёте копию массива и не изменяете его, обе переменные будут указывать на одни и те же данные в памяти. Как только вы модифицируете одну из копий, Swift создаст реальную копию данных для этой копии, обеспечивая независимость данных между оригиналом и копией.var originalArray = [1, 2, 3]
var copiedArray = originalArray // На этом этапе данные не дублируются
copiedArray.append(4) // Теперь данные копируются, потому что copiedArray модифицируется
В этом примере до вызова
append обе переменные, originalArray и copiedArray, ссылаются на один и тот же набор данных. Модификация copiedArray активирует механизм CoW, и Swift создаёт реальную копию данных для copiedArray.Можно реализовать для своих собственных типов данных. Это может быть полезно для эффективного управления памятью и повышения производительности при работе с большими или сложными структурами данных. Для реализации CoW в своих типах необходимо вручную проверять, является ли экземпляр типа уникальной ссылкой, и копировать данные при необходимости, обычно используя методы для работы с памятью, такие как
isKnownUniquelyReferenced().Copy-on-Write — это механизм оптимизации, который позволяет отложить копирование данных до момента их реальной модификации. Это улучшает производительность и эффективность использования памяти, особенно при работе с большими структурами данных. Swift автоматически применяет CoW к своим стандартным коллекциям, таким как
Array, String, Dictionary,и Set.Please open Telegram to view this post
    VIEW IN TELEGRAM
  Anonymous Quiz
    74%
    enum Name: String { case A = "Apple", B = "Banana" }
      
    16%
    enum Name { case A = "Apple", case B = "Banana" }
      
    4%
    enum Name(String) { case A = "Apple", case B = "Banana" }
      
    5%
    type enum Name: String { case A = "Apple", case B = "Banana" }
      
    MVVM (Model-View-ViewModel) — это архитектурный паттерн, разработанный для упрощения создания пользовательского интерфейса, который был впервые представлен Microsoft для использования с Windows Presentation Foundation (WPF) и Silverlight. С тех пор он нашёл широкое применение в различных технологиях разработки программного обеспечения, включая разработку под iOS и Android. MVVM помогает разделить логику представления интерфейса (UI) от бизнес-логики и логики приложения, упрощая тестирование и поддержку.
MVVM может быть реализован с использованием различных фреймворков и технологий, таких как RxSwift или Combine, которые предоставляют мощные инструменты для реализации привязки данных и управления потоками данных. Это позволяет разработчикам создавать реактивные приложения, где View автоматически обновляется в ответ на изменения данных, обеспечивая более плавный и интуитивно понятный пользовательский опыт.
MVVM не только способствует созданию более чистого и организованного кода, но и облегчает сотрудничество в командах, позволяя разработчикам интерфейса и логики приложения работать более независимо.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Anonymous Quiz
    2%
    protocol MyProtocol { mandatory func myMethod() }
      
    14%
    protocol MyProtocol { required func myMethod() }
      
    82%
    protocol MyProtocol { func myMethod() }
      
    1%
    define protocol MyProtocol { func myMethod() }
      
    Жизненный цикл приложения определяет ключевые состояния, через которые проходит приложение в процессе его запуска, работы и завершения. Основные состояния управляются классом
UIApplication и его делегатом UIApplicationDelegate, который предоставляет разработчикам набор методов для реагирования на переходы между этими состояниями. Вот основные этапы жизненного цикла:Приложение ещё не было запущено или было завершено.
Приложение запущено, но не получает события. Это может произойти в моменты временного перерыва, например, во время перехода из одного состояния в другое, или когда система ожидает ответа от пользователя или приложения.
Приложение активно и получает события. Это основное рабочее состояние приложения, когда пользователь взаимодействует с его интерфейсом.
Приложение находится в фоновом режиме и может выполнять код. Приложение переходит в это состояние из активного состояния, когда пользователь переключается на другое приложение или на главный экран. Приложения могут запросить дополнительное время для завершения задач в фоновом режиме.
Приложение находится в фоновом режиме, но не выполняет код. Операционная система может автоматически перевести приложение из фонового состояния в приостановленное для освобождения ресурсов. Приложение остается в памяти, но любые активные задачи, потоки или таймеры останавливаются.
Методы AppDelegate для управления жизненным циклом
Разработчики могут реагировать на изменения в жизненном цикле, используя методы делегата
UIApplicationDelegate, такие как:application(_:didFinishLaunchingWithOptions:) — вызывается, когда приложение завершает запуск.➕ applicationDidBecomeActive(_:) — вызывается, когда приложение становится активным.applicationWillResignActive(_:) — вызывается, когда приложение переходит из активного состояния в неактивное.applicationDidEnterBackground(_:) — вызывается, когда приложение переходит в фоновый режим.applicationWillEnterForeground(_:) — вызывается перед переходом приложения из фонового режима в активный.applicationWillTerminate(_:) — вызывается перед тем, как приложение будет завершено.Понимание жизненного цикла приложения критически важно для разработки стабильных и эффективных приложений на iOS, поскольку оно позволяет корректно управлять ресурсами, сохранять и восстанавливать состояние приложения и реагировать на действия пользователя и системы.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Anonymous Quiz
    1%
    let array = [Int]()
      
    95%
    var array = [Int]()
      
    1%
    const array = [Int]()
      
    3%
    array<int> = []
      
    Опционалы — это особенность языка, позволяющая обрабатывать ситуации, когда значение может отсутствовать. Может содержать либо значение соответствующего типа, либо
nil, указывая на отсутствие значения. Это позволяет безопасно работать с данными, которые могут быть не предоставлены, избегая при этом ошибок выполнения, связанных с обращением к переменным, не имеющим фактического значения.Их использование помогает предотвратить ситуации, когда программа пытается обратиться к значению, которое не было задано, что может привести к сбою программы. Они требуют явного развертывания для доступа к их содержимому, что заставляет осознанно обрабатывать случаи, когда значение отсутствует.
var optionalInt: Int? = nil
В этом случае переменная
optionalInt объявлена как опциональная Int. Изначально она не содержит значения, что обозначается как nil.Предлагается несколько способов работы с опционалами, включая:
!) для доступа к значению опционала. Этот метод опасен, так как может привести к ошибке времени выполнения, если опционал содержит nil.let someValue: Int? = 5
let unwrappedValue: Int = someValue! // Принудительное развертывание
if let unwrappedValue = someValue {
    print(unwrappedValue) // Безопасное использование unwrappedValue
}nil.let defaultValue = someValue ?? 0 // Использует 0, если someValue содержит nil
Использование опционалов является ключевым для обеспечения безопасности типов и предотвращения распространенных ошибок, связанных с обращением к неинициализированным или отсутствующим значениям.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Anonymous Quiz
    48%
    `?`
      
    4%
    `!`
      
    47%
    `??`
      
    1%
    `&`
      
    🤔1
  MVC (Model-View-Controller) и MVVM (Model-View-ViewModel) — это два популярных архитектурных паттерна, используемых в разработке ПО для организации кода и разделения ответственности между компонентами системы. Оба паттерна направлены на упрощение разработки и поддержки приложений, но они делают это по-разному.
Выбор между MVC и MVVM зависит от конкретного проекта, предпочтений команды и требований к архитектуре приложения. MVVM часто предпочтителен для приложений с сложным пользовательским интерфейсом и динамическими данными из-за его гибкости и упрощения тестирования.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥2
  Anonymous Quiz
    95%
    print()
      
    2%
    println()
      
    0%
    echo()
      
    2%
    console.log()
      
    👾1
  Цикл удержания (Retain Cycle) — это проблема управления памятью, которая возникает в языках программирования с автоматическим подсчётом ссылок (например, в Swift и Objective-C), когда два объекта хранят сильные (strong) ссылки друг на друга. Это приводит к тому, что объекты не освобождаются автоматически после того, как становятся ненужными, потому что счетчик ссылок на каждый из них остаётся больше нуля. В результате память, которую занимают эти объекты, утекает, что может привести к избыточному расходу памяти и в конечном итоге к снижению производительности или даже к аварийному завершению работы приложения.
Представьте себе два объекта
A и B. Объект A имеет сильную ссылку на объект B, а объект B в свою очередь имеет сильную ссылку на объект A. В такой ситуации, даже если внешние ссылки на эти объекты будут удалены, они всё равно не будут освобождены из-за взаимных сильных ссылок, которые поддерживают счетчик ссылок каждого из объектов больше нуля.weak и unowned ссылки не увеличивают счетчик ссылок объекта, на который они указывают, что предотвращает возникновение цикла удержания.nil. Swift автоматически обнуляет слабую ссылку, когда объект, на который она указывает, освобождается.class Parent {
    var child: Child?
}
class Child {
    weak var parent: Parent?
}
var parent: Parent? = Parent()
var child: Child? = Child()
parent?.child = child
child?.parent = parent
// Разрыв ссылок
parent = nil
child = nilВ этом примере
parent имеет сильную ссылку на child, но child имеет слабую ссылку на parent. Это предотвращает возникновение цикла удержания, и объекты могут быть корректно освобождены из памяти.Цикл удержания — это ситуация, при которой два объекта ссылаются друг на друга сильными ссылками, предотвращая их освобождение и вызывая утечку памяти. Использование слабых (
weak) или некрепких (unowned) ссылок помогает избежать этих циклов и обеспечивает корректное управление памятью в приложениях на Swift и Objective-C.Please open Telegram to view this post
    VIEW IN TELEGRAM
  Anonymous Quiz
    11%
    var
      
    84%
    let
      
    3%
    const
      
    1%
    static
      
    Responder chain (цепочка обработчиков событий) — это концепция, используемая для обработки событий, таких как касания, жесты, нажатия клавиш и другие пользовательские действия. Она представляет собой последовательность объектов (responders), которые могут реагировать на эти события. Цепочка обработчиков позволяет событию быть переданным от одного объекта к другому, пока не будет найден подходящий обработчик события или пока цепочка не будет завершена.
ViewController этого представления. Затем ViewController может обработать событие или передать его дальше по цепочке.ViewControllers не обработал событие, оно может быть передано объекту приложения (UIApplication) и, в конечном счёте, его делегату (AppDelegate), где оно может быть обработано или проигнорировано.Представим ситуацию, когда пользователь нажимает на кнопку, но код обработки события нажатия отсутствует в классе этой кнопки. В таком случае событие будет передано родительскому представлению кнопки. Если и родительское представление не обрабатывает это событие, оно продолжит передаваться вверх по иерархии представлений, пока не найдет подходящий обработчик или не достигнет конца цепочки.
Responder chain позволяет создавать гибкую архитектуру обработки событий, где события могут быть обработаны на разных уровнях приложения. Это обеспечивает большую модульность и разделение ответственности между компонентами приложения. Кроме того, это упрощает добавление новых типов обработчиков событий, не нарушая существующую логику приложения.
Responder chain — это система для передачи и обработки событий, которая обеспечивает последовательную передачу событий от одного объекта к другому в пределах иерархии приложения, пока событие не будет обработано или не достигнет конца цепочки. Это ключевой механизм для обработки пользовательского ввода и других событий в приложениях для платформ Apple.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  