Swift | Вопросы собесов
2.13K subscribers
28 photos
951 links
Download Telegram
🤔 Чем отличаются слабые и сильные ссылки?

- Сильные ссылки (strong): увеличивают счётчик ссылок объекта, предотвращая его удаление.
- Слабые ссылки (weak): не увеличивают счётчик ссылок, используются для предотвращения циклических зависимостей.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
🤔 Как устроено наследование?

Это ключевой механизм ООП, позволяющий классам наследовать свойства, методы и другие характеристики от других классов. Это позволяет создавать новые классы на основе существующих, расширяя их функциональность или изменяя её.

🚩Основы наследования

🟠Определение базового класса
Базовый класс определяет общие свойства и методы, которые могут быть унаследованы подклассами.

🟠Создание подкласса
Подкласс наследует (или "расширяет") базовый класс. Он может переопределять унаследованные методы и свойства, добавлять новые методы и свойства, а также добавлять инициализаторы или изменять существующие.

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

🟠Предотвращение переопределения
Можно предотвратить переопределение методов, свойств или индексаторов с помощью ключевого слова final. Если метод, свойство или индексатор объявлен как final, то он не может быть переопределён в подклассе.
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// Этот метод будет переопределен в подклассах, если необходимо
}
}

class Bicycle: Vehicle {
var hasBasket = false
}

class Car: Vehicle {
var gear = 1
final func drive() {
print("Car is moving")
}
override func makeNoise() {
print("Vroom!")
}
}


🚩Использование super

Подклассы могут вызывать методы своего суперкласса с помощью ключевого слова super. Это позволяет подклассам расширять, а не заменять поведение суперкласса.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое Grand Central Dispatch (GCD)?

Это технология для работы с многопоточностью в iOS и macOS. Она управляет очередями задач (sync/async, serial/concurrent) и позволяет эффективно распределять задачи между потоками.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 За счёт чего стек быстрее кучи?

Обычно имеют в виду различия между использованием стека вызовов (память стека) и кучи (heap) в контексте управления памятью в программировании. Эти два типа памяти имеют разные способы выделения и освобождения памяти, каждый со своими преимуществами и недостатками.

🟠Способ выделения памяти
Память в стеке выделяется и освобождается по очень простому и быстрому принципу: LIFO (Last In, First Out). Это означает, что для выделения памяти достаточно переместить указатель стека вверх (при добавлении данных) или вниз (при удалении данных). Этот процесс почти мгновенен и не требует дополнительных вычислений.
В куче память выделяется динамически, что требует управления доступными блоками памяти. Аллокатор памяти должен найти достаточно большой свободный блок, что может занять значительное время, особенно если память фрагментирована. Также освобождение памяти в куче требует более сложной обработки, включая возможную дефрагментацию.

🟠Скорость доступа
Доступ к данным в стеке очень быстрый, потому что данные всегда добавляются и удаляются с "вершины" стека, где находится указатель стека. Это делает доступ к текущим локальным переменным очень быстрым и предсказуемым. Доступ к данным в куче может быть менее эффективным, поскольку данные могут быть разбросаны по разным частям памяти. Кроме того, дополнительное время требуется для поиска и управления блоками памяти.

🟠Детерминированное управление памятью
Его память автоматически очищается при выходе из области видимости, что упрощает управление памятью и снижает риск утечек памяти. Память, выделенная в куче, остаётся занятой до тех пор, пока явно не будет освобождена. Это увеличивает риск утечек памяти, если разработчик забудет освободить память.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Что под капотом кучи?

Это область памяти, управляемая системой, где объекты выделяются динамически. Управление включает:
- Аллокацию памяти.
- Освобождение через сборщик мусора (в Java, Swift) или вручную (в C++).
- Компактирование для предотвращения фрагментации.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2🤯2👍1
🤔 Что под капотом стэка?

Это абстрактная структура данных, работающая по принципу LIFO (Last In, First Out), что означает "последний пришёл — первый вышел". Это значит, что последний добавленный элемент будет первым при извлечении из стека. Под капотом реализации стека могут быть разные, и они зависят от конкретного языка программирования и задач, которые необходимо решить.

🟠Массивы
Один из самых распространённых способов реализации стека — это использование массива. В такой реализации элементы стека хранятся в массиве, и индекс последнего элемента (вершина стека) отслеживается отдельной переменной.
struct Stack<Element> {
private var storage: [Element] = []

mutating func push(_ element: Element) {
storage.append(element)
}

mutating func pop() -> Element? {
return storage.popLast()
}

func peek() -> Element? {
return storage.last
}

var isEmpty: Bool {
return storage.isEmpty
}
}


🟠Связные списки
Стек можно реализовать с использованием связных списков, где каждый элемент списка содержит данные и ссылку на следующий элемент в стеке. Вершина стека в такой реализации — это начало связного списка.
class Node<Element> {
var value: Element
var next: Node?

init(value: Element) {
self.value = value
}
}

struct Stack<Element> {
private var head: Node<Element>?

mutating func push(_ element: Element) {
let node = Node(value: element)
node.next = head
head = node
}

mutating func pop() -> Element? {
let node = head
head = head?.next
return node?.value
}

func peek() -> Element? {
return head?.value
}

var isEmpty: Bool {
return head == nil
}
}


🟠Стек вызовов
Это системный стек, который используется во время выполнения программы для хранения информации о вызовах функций/методов. Он хранит адреса возврата, параметры функций, локальные переменные и другие данные, необходимые для управления вызовами функций и их возврата.

🚩Зачем он нужен?

Обратную польскую нотацию для вычисления арифметических выражений. Управление вызовами функций в программном стеке. Поддержка операций undo в приложениях.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
4
🤔 Когда value типы могут стать reference?

Value типы становятся reference, если они упакованы (например, через Box в Swift) или если они хранятся в контейнерах, которые управляются ссылочным механизмом (например, массивы при копировании).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как создаешь анимации в приложении?

В iOS-приложениях можно создавать анимации несколькими способами.

🟠Использование `UIView.animate`
Самый простой способ анимации представлений (views) в iOS - это использование метода UIView.animate. Вот пример кода, который изменяет положение и прозрачность представления за 1 секунду:
UIView.animate(withDuration: 1.0) {
myView.frame.origin.y += 100
myView.alpha = 0.5
}


🟠Использование `CABasicAnimation`
Для более сложных анимаций можно использовать Core Animation, например, CABasicAnimation. Вот пример анимации изменения позиции слоя (layer):
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = NSValue(cgPoint: CGPoint(x: 50, y: 50))
animation.toValue = NSValue(cgPoint: CGPoint(x: 150, y: 150))
animation.duration = 1.0
myView.layer.add(animation, forKey: "positionAnimation")


🟠Использование `UIViewPropertyAnimator`
Этот класс предоставляет более детальный контроль над анимациями. Его можно использовать для создания и управления анимациями в реальном времени:
let animator = UIViewPropertyAnimator(duration: 1.0, curve: .easeInOut) {
myView.frame.origin.y += 100
myView.alpha = 0.5
}
animator.startAnimation()


🟠Использование анимаций с пружинным эффектом
Для создания реалистичных анимаций с пружинным эффектом можно использовать метод UIView.animate с параметрами пружинного демпфирования:
UIView.animate(withDuration: 1.0,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.5,
options: [],
animations: {
myView.frame.origin.y += 100
myView.alpha = 0.5
}, completion: nil)


🟠Анимация переходов между контроллерами
Для анимации переходов между экранами используется UIViewControllerAnimatedTransitioning. Это требует реализации методов протокола UIViewControllerAnimatedTransitioning:
class CustomTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else { return }

transitionContext.containerView.addSubview(toView)
toView.alpha = 0.0

UIView.animate(withDuration: 0.5, animations: {
toView.alpha = 1.0
}, completion: { finished in
transitionContext.completeTransition(finished)
})
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое UIResponder?

Это базовый класс для обработки событий в UIKit. Объекты типа UIView, UIViewController, UIApplication наследуются от UIResponder и участвуют в цепочке обработки событий, таких как нажатия, свайпы или жесты.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое unowned?

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

🚩Когда использовать?

🟠Оба объекта существуют одновременно
Например, если один объект никогда не будет существовать дольше другого объекта, и тем самым вы уверены, что ссылка всегда будет действительной.

🟠Избегание циклов сильных ссылок
Чтобы предотвратить циклы сильных ссылок, которые могут привести к утечкам памяти.

🚩Пример использования `unowned`

``` swift
class Person {
let name: String
var creditCard: CreditCard?

init(name: String) {
self.name = name
}

deinit {
print("\(name) is being deinitialized")
}
}

class CreditCard {
let number: String
unowned let owner: Person

init(number: String, owner: Person) {
self.number = number
self.owner = owner
}

deinit {
print("CreditCard #\(number) is being deinitialized")
}
}

// Пример использования
var john: Person? = Person(name: "John Appleseed")
john?.creditCard = CreditCard(number: "1234 5678 9012 3456", owner: john!)

john = nil
```

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое деинициализатор?

Это метод, который вызывается перед удалением объекта из памяти. В Swift используется метод deinit. Он позволяет выполнять действия, такие как освобождение ресурсов или закрытие соединений, когда объект больше не нужен.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое очередь?

Это структура данных, которая работает по принципу "первым пришел - первым ушел" (FIFO, First In, First Out). Это значит, что элементы добавляются в конец очереди и извлекаются из начала очереди.

🚩Основные операции с очередью

🟠Добавление (enqueue)
Вставка элемента в конец очереди.
🟠Удаление (dequeue)
Удаление элемента из начала очереди.
🟠Проверка первого элемента (peek)
Просмотр элемента в начале очереди без его удаления.
🟠Проверка на пустоту (isEmpty)
Проверка, содержит ли очередь элементы.

🚩Примеры использования

Очереди часто используются в задачах, где порядок обработки элементов важен.
Управление задачами в системах реального времени.
Обработка запросов в сетевых приложениях.
Имплементация алгоритмов обхода графов (например, поиск в ширину).

struct Queue<T> {
private var elements: [T] = []

// Добавление элемента в конец очереди
mutating func enqueue(_ element: T) {
elements.append(element)
}

// Удаление элемента из начала очереди
mutating func dequeue() -> T? {
return isEmpty ? nil : elements.removeFirst()
}

// Просмотр элемента в начале очереди
func peek() -> T? {
return elements.first
}

// Проверка на пустоту
var isEmpty: Bool {
return elements.isEmpty
}
}

// Пример использования
var queue = Queue<Int>()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)

print(queue.dequeue() ?? "Queue is empty") // Вывод: 1
print(queue.peek() ?? "Queue is empty") // Вывод: 2


🚩Варианты использования в iOS

🟠Очереди задач (DispatchQueue)
GCD (Grand Central Dispatch) использует очереди для управления многозадачностью. Например, DispatchQueue.main.async добавляет задачи в очередь для выполнения на главном потоке:
DispatchQueue.main.async {
// Код выполняется на главном потоке
}


🟠Операционные очереди (OperationQueue)
Используются для управления и упорядочивания выполнения множества Operation объектов:
let queue = OperationQueue()
queue.addOperation {
print("Operation 1")
}
queue.addOperation {
print("Operation 2")
}


Ставь
👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое retain/release?

Это механизм управления памятью в системах с подсчетом ссылок (Reference Counting):
1. Retain: увеличивает счетчик ссылок объекта, указывая, что объект используется.
2. Release: уменьшает счетчик ссылок. Когда счетчик достигает нуля, объект освобождается из памяти.
Эта модель широко использовалась в Objective-C до появления ARC (Automatic Reference Counting).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Знаешь, что относится к value типам помимо структур в свифте?

В Swift, помимо структур (structs), к типам-значениям (value types) также относятся перечисления (enums) и кортежи (tuples).

🟠Структуры (structs)
Структуры в Swift являются типами-значениями. Когда вы создаете копию структуры, вы получаете новый экземпляр со своим собственным набором данных. Изменения в одном экземпляре не влияют на другие экземпляры.
struct Point {
var x: Int
var y: Int
}

var point1 = Point(x: 0, y: 0)
var point2 = point1
point2.x = 10

print(point1.x) // Вывод: 0
print(point2.x) // Вывод: 10


🟠Перечисления (enums)
Перечисления также являются типами-значениями. При копировании экземпляра перечисления создается новый экземпляр с тем же значением.
enum CompassDirection {
case north, south, east, west
}

var direction1 = CompassDirection.north
var direction2 = direction1
direction2 = .south

print(direction1) // Вывод: north
print(direction2) // Вывод: south


🟠Кортежи (tuples)
Кортежи в Swift тоже являются типами-значениями. Кортежи позволяют объединять несколько значений в одну составную единицу. При копировании кортежа создается новый кортеж с теми же значениями.
var tuple1 = (a: 1, b: 2)
var tuple2 = tuple1
tuple2.a = 3

print(tuple1.a) // Вывод: 1
print(tuple2.a) // Вывод: 3


🚩Отличия типов-значений от ссылочных типов

Типы-значения копируются при передаче и присваивании, а ссылочные типы (классы и замыкания) передаются по ссылке. Это важное различие влияет на то, как изменяются данные при передаче между переменными и функциями.

🚩Пример с классами для сравнения

Для сравнения, классы являются ссылочными типами (reference types). При копировании экземпляра класса копируется не сам объект, а ссылка на него. Поэтому изменения в одном экземпляре отражаются на всех его копиях.
class Person {
var name: String
init(name: String) {
self.name = name
}
}

var person1 = Person(name: "John")
var person2 = person1
person2.name = "Doe"

print(person1.name) // Вывод: Doe
print(person2.name) // Вывод: Doe


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Есть ли у unowned ссылок счетчик?

Нет, у unowned ссылок нет собственного счетчика ссылок. Они не увеличивают счетчик объекта, к которому ссылаются. Это означает, что если объект удален из памяти, попытка обращения к unowned ссылке вызовет runtime-ошибку.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
🤔 Какие есть структуры данных?

В Swift и других языках программирования существует множество структур данных, каждая из которых предназначена для эффективного хранения, организации и управления данными.

🟠Массивы (Arrays)
Это упорядоченные коллекции элементов, которые хранятся в непрерывной области памяти. Массивы позволяют быстро получать доступ к элементам по индексу.
var numbers: [Int] = [1, 2, 3, 4, 5]
print(numbers[2]) // Вывод: 3


🟠Словари (Dictionaries)
Это коллекции пар "ключ-значение", которые позволяют быстро находить значения по ключу. Ключи в словаре должны быть уникальными.
var capitalCities: [String: String] = ["France": "Paris", "Japan": "Tokyo"]
print(capitalCities["France"]!) // Вывод: Paris


🟠Множества (Sets)
Это неупорядоченные коллекции уникальных элементов. Они полезны, когда необходимо проверить наличие элемента или выполнить операции над множествами, такие как объединение или пересечение.
var uniqueNumbers: Set<Int> = [1, 2, 3, 4, 5, 1]
print(uniqueNumbers) // Вывод: [5, 2, 3, 1, 4]


🟠Связные списки (Linked Lists)
Это последовательности элементов, где каждый элемент содержит ссылку на следующий элемент. Связные списки могут быть односвязными (только вперед) или двусвязными (вперед и назад).
class ListNode {
var value: Int
var next: ListNode?

init(value: Int) {
self.value = value
}
}

let head = ListNode(value: 1)
head.next = ListNode(value: 2)
head.next?.next = ListNode(value: 3)


🟠Стеки (Stacks)
Это структура данных, работающая по принципу "последним пришел - первым ушел" (LIFO, Last In, First Out). Стек поддерживает две основные операции: добавление (push) и удаление (pop) элемента.
var stack: [Int] = []
stack.append(1) // push
stack.append(2)
print(stack.pop()!) // pop, вывод: 2


🟠Очереди (Queues)
Это структура данных, работающая по принципу "первым пришел - первым ушел" (FIFO, First In, First Out). Очередь поддерживает операции добавления (enqueue) и удаления (dequeue) элемента.
var queue: [Int] = []
queue.append(1) // enqueue
queue.append(2)
print(queue.removeFirst()) // dequeue, вывод: 1


🟠Деревья (Trees)
Это иерархическая структура данных, состоящая из узлов, где каждый узел имеет одно родительское и ноль или более дочерних узлов. Наиболее распространенный тип дерева - бинарное дерево, где каждый узел имеет не более двух потомков.
class TreeNode {
var value: Int
var left: TreeNode?
var right: TreeNode?

init(value: Int) {
self.value = value
}
}

let root = TreeNode(value: 1)
root.left = TreeNode(value: 2)
root.right = TreeNode(value: 3)


🟠Графы (Graphs)
Это набор узлов (вершин), соединенных ребрами. Графы могут быть направленными или ненаправленными, взвешенными или невзвешенными.
class GraphNode {
var value: Int
var neighbors: [GraphNode] = []

init(value: Int) {
self.value = value
}
}

let node1 = GraphNode(value: 1)
let node2 = GraphNode(value: 2)
let node3 = GraphNode(value: 3)
node1.neighbors = [node2, node3]
node2.neighbors = [node1]
node3.neighbors = [node1]


🟠Хеш-таблицы (Hash Tables)
Это структура данных, которая реализует словарь с использованием хеш-функции для быстрого доступа к данным по ключу.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
3
🤔 Зачем сделан сайд-таблица (side table)?

Сайд-таблица используется для хранения дополнительной информации об объектах, управляемых системой подсчета ссылок:
1. Счетчик ссылок: хранится для каждого объекта.
2. Другие данные: например, слабые ссылки (weak references) или ассоциированные объекты.
Она позволяет эффективно управлять объектами без увеличения их базового размера.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 В чем плюсы и минусы autolayout и frame?

В iOS разработке существует два основных способа управления расположением и размером пользовательского интерфейса: Auto Layout и использование фреймов (frames). Давайте рассмотрим плюсы и минусы каждого из них.

🚩Auto Layout

Плюсы

Адаптивность
Auto Layout позволяет создавать интерфейсы, которые адаптируются к разным размерам экранов и ориентациям устройств. Это особенно важно для поддержки различных устройств, включая iPhone и iPad.

Реакция на изменения
Легко изменять пользовательский интерфейс при изменении содержимого или размера экрана, например, при повороте устройства.

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

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

Гибкость
Позволяет создавать сложные интерфейсы с минимальными усилиями благодаря использованию констрейнтов (constraints).

Минусы

Сложность
Может быть сложным для изучения и освоения, особенно для начинающих разработчиков.

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

Версия Xcode
Требует использования более новых версий Xcode для получения всех возможностей и улучшений.

🚩Frames

Плюсы

Простота
Легко понимать и использовать, особенно для простых интерфейсов или прототипов.

Производительность
Чаще всего более быстрый способ размещения элементов интерфейса, так как не требует вычислений для констрейнтов.

Контроль
Полный контроль над положением и размером каждого элемента интерфейса.

Минусы

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

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

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

Сложные интерфейсы
Создание сложных интерфейсов может быть затруднено и занять много времени.

🚩Примеры использования

Auto Layout
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
button.widthAnchor.constraint(equalToConstant: 100),
button.heightAnchor.constraint(equalToConstant: 50)
])


Frames
let button = UIButton()
button.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
view.addSubview(button)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 В контексте цикла ссылок как помогает кэпчур-лист?

Кэпчур-лист в замыканиях ([weak self] или [unowned self]) предотвращает образование сильных ссылок на объект. Это разрывает цикл ссылок между замыканием и объектом, позволяя последнему быть корректно освобожденным из памяти.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое notification центр?

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

🚩Основные аспекты

🟠Отправка уведомлений
Любой объект может отправить уведомление с помощью Notification Center. Уведомления идентифицируются по имени (Notification.Name). Можно передать дополнительную информацию в виде словаря (userInfo).
NotificationCenter.default.post(name: .myNotification, object: nil)   


🟠Получение уведомлений
Объекты могут регистрироваться для получения уведомлений с определенным именем. Для обработки уведомлений используется метод, который будет вызван при получении уведомления.
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: .myNotification, object: nil)

@objc func handleNotification(notification: Notification) {
print("Received notification")
}


🟠Удаление наблюдателей
Важно удалять наблюдателей, когда они больше не нужны, чтобы избежать утечек памяти. Обычно это делается в методе deinit или перед уничтожением объекта.
NotificationCenter.default.removeObserver(self, name: .myNotification, object: nil)   


🚩Плюсы

Слабая связанность
Объекты не нужно напрямую ссылаться друг на друга, что улучшает модульность кода.
Гибкость
Позволяет легко организовать обмен сообщениями между различными частями приложения.
Повторное использование
Уведомления могут использоваться многими объектами, что облегчает реализацию функций, таких как обновление интерфейса или реагирование на события.

🚩Примеры использования

1⃣Обновление интерфейса
Когда данные изменяются, можно отправить уведомление для обновления пользовательского интерфейса.
NotificationCenter.default.post(name: .dataDidUpdate, object: nil)   


2⃣Реакция на системные события
Например, можно подписаться на уведомление о смене состояния сети.
NotificationCenter.default.addObserver(self, selector: #selector(handleNetworkChange), name: .reachabilityChanged, object: nil)   


3⃣Межмодульное взаимодействие
Различные модули приложения могут общаться друг с другом через Notification Center, не создавая сильных зависимостей.
NotificationCenter.default.post(name: .userDidLogin, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateUI), name: .userDidLogin, object: nil)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM