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

💬 Спрашивают в 18% собеседований

В Swift ссылки (references) на объекты могут быть сильными (strong) и слабыми (weak). Они отличаются способом управления памятью и временем жизни объектов, на которые ссылаются.

🤔 Сильные ссылки (Strong References)

Описание: Сильная ссылка (strong reference) удерживает объект в памяти. Пока существует хотя бы одна сильная ссылка на объект, он не будет удалён из памяти.

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

🤔 Пример использования:
class Person {
var name: String
init(name: String) {
self.name = name
}
}

var person1: Person? = Person(name: "Alice")
var person2: Person? = person1 // person2 имеет сильную ссылку на тот же объект, что и person1

person1 = nil // Объект все еще удерживается в памяти благодаря person2
print(person2?.name) // Output: Alice

person2 = nil // Теперь объект будет удалён из памяти, так как нет сильных ссылок


🤔 Слабые ссылки (Weak References)

Описание: Слабая ссылка (weak reference) не удерживает объект в памяти. Если объект больше не имеет сильных ссылок, он будет удалён из памяти, даже если на него существуют слабые ссылки.

Применение: Слабые ссылки используются для предотвращения циклических ссылок, которые могут привести к утечкам памяти.

🤔 Пример использования:
class Person {
var name: String
init(name: String) {
self.name = name
}
}

class Apartment {
var tenant: Person?
init(tenant: Person?) {
self.tenant = tenant
}
}

var alice: Person? = Person(name: "Alice")
var apartment: Apartment? = Apartment(tenant: alice)

// Создание слабой ссылки для предотвращения циклической зависимости
class Tenant {
var name: String
weak var apartment: Apartment? // Слабая ссылка
init(name: String) {
self.name = name
}
}

let tenant = Tenant(name: "Bob")
apartment?.tenant = alice

alice = nil // Объект Person будет удалён из памяти, так как больше нет сильных ссылок
print(apartment?.tenant?.name) // Output: nil


🤔 Основные различия между сильными и слабыми ссылками

1️⃣ Удержание в памяти:

Сильные ссылки: Удерживают объект в памяти. Объект будет освобождён только тогда, когда все сильные ссылки на него будут удалены.

Слабые ссылки: Не удерживают объект в памяти. Объект будет освобождён, когда не останется сильных ссылок.

2️⃣ Использование:

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

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

3️⃣ Обнуление:

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

Слабые ссылки: Автоматически обнуляются, когда объект, на который они ссылаются, удаляется из памяти.

🤔 Заключение

Сильные и слабые ссылки в Swift различаются по способу управления памятью и временем жизни объектов. Сильные ссылки удерживают объекты в памяти, тогда как слабые ссылки позволяют объектам быть удалёнными, предотвращая циклические ссылки и утечки памяти.

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
📌 Grand Central Dispatch?

💬 Спрашивают в 18% собеседований

Grand Central Dispatch (GCD) — это мощная технология в iOS и macOS, предоставляемая Apple для управления многопоточностью и параллелизмом в приложениях. GCD позволяет легко выполнять задачи асинхронно, управлять очередями задач и эффективно использовать системные ресурсы. Вот основные аспекты GCD:

🤔 Основные концепции GCD

1️⃣ Очереди задач (Dispatch Queues)

Сериализованные очереди (Serial Queues): Задачи выполняются последовательно, одна за другой.

Конкурентные очереди (Concurrent Queues): Задачи могут выполняться параллельно, в произвольном порядке.

2️⃣ Главная очередь (Main Queue)

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

3️⃣ Глобальные очереди (Global Queues)

Конкурентные очереди, предоставляемые системой, с различными уровнями качества обслуживания (QoS), такими как user-interactive, user-initiated, default, utility, background и unspecified.

🤔 Основные функции GCD

1️⃣ Создание очередей

Сериализованные очереди:
  let serialQueue = DispatchQueue(label: "com.example.serialQueue")


Конкурентные очереди:
  let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)


2️⃣ Асинхронное выполнение задач

Асинхронное выполнение на глобальной очереди:
  DispatchQueue.global(qos: .background).async {
// Долгосрочная фоновая задача
print("Background task")
}


Асинхронное выполнение на пользовательской очереди:
  let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
// Задача в пользовательской сериализованной очереди
print("Serial queue task")
}


3️⃣ Синхронное выполнение задач

Синхронное выполнение задачи на пользовательской очереди:
  let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.sync {
// Синхронная задача
print("Sync task")
}


4️⃣ Отложенное выполнение задач

Выполнение задачи с задержкой:
  let delay = DispatchTime.now() + .seconds(5)
DispatchQueue.main.asyncAfter(deadline: delay) {
// Задача, выполненная через 5 секунд
print("Delayed task")
}


5️⃣ Группы задач (Dispatch Groups)

Группы задач для отслеживания завершения нескольких задач:
  let group = DispatchGroup()

let queue = DispatchQueue.global()

group.enter()
queue.async {
// Первая задача
print("First task")
group.leave()
}

group.enter()
queue.async {
// Вторая задача
print("Second task")
group.leave()
}

group.notify(queue: DispatchQueue.main) {
// Все задачи завершены
print("All tasks are done")
}


6️⃣ Барьерные задачи (Barrier Tasks)

Барьерные задачи для обеспечения эксклюзивного доступа к ресурсу:
  let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)

concurrentQueue.async(flags: .barrier) {
// Барьерная задача
print("Barrier task")
}


🤔 Преимущества GCD

1️⃣ Простота использования: GCD упрощает многопоточность и параллелизм, позволяя разработчикам легко добавлять асинхронные задачи.

2️⃣ Эффективность: GCD оптимизирует использование системных ресурсов, автоматически управляя количеством активных потоков.

3️⃣ Безопасность: Использование очередей и групп задач помогает избежать ошибок, связанных с состоянием гонки и синхронизацией.

🤔 Заключение

Grand Central Dispatch (GCD) — это мощная и простая в использовании технология для управления многопоточностью и параллелизмом в приложениях iOS и macOS. Она предоставляет разработчикам средства для выполнения задач асинхронно, управления очередями задач и эффективного использования системных ресурсов.

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥21
🤔 Какой протокол должен реализовать тип, чтобы поддерживать сравнение по значению?
Anonymous Quiz
13%
Hashable
30%
Comparable
55%
Equatable
2%
Codable
👍2
📌 Что под капотом кучи?

💬 Спрашивают в 18% собеседований

Куча (heap) в Swift управляется с помощью механизма автоматического управления памятью (ARC), который использует подсчёт ссылок (reference counting) для автоматического выделения и освобождения памяти. Рассмотрим основные аспекты и типы ссылок:

🤔 Основные концепции

1️⃣ Сильные ссылки (Strong References)

Удерживают объект в памяти, увеличивая счётчик ссылок.

Объект освобождается, когда счётчик ссылок достигает нуля.
   class Person {
let name: String
init(name: String) { self.name = name }
}

var person1: Person? = Person(name: "Alice") // Счётчик ссылок: 1
var person2: Person? = person1 // Счётчик ссылок: 2

person1 = nil // Счётчик ссылок: 1
person2 = nil // Счётчик ссылок: 0, объект освобождается


2️⃣ Слабые ссылки (Weak References)

Не удерживают объект в памяти.

Автоматически обнуляются, когда объект освобождается.
   class Apartment {
weak var tenant: Person?
}

var alice: Person? = Person(name: "Alice")
var apartment = Apartment()
apartment.tenant = alice

alice = nil // Объект освобождается, так как слабые ссылки не удерживают объект в памяти


3️⃣ Неустранимые ссылки (Unowned References)

Используются для устранения циклических зависимостей.

Предполагается, что объект будет существовать в течение всего жизненного цикла другого объекта.
   class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}

class CreditCard {
let number: Int
unowned let customer: Customer
init(number: Int, customer: Customer) {
self.number = number
self.customer = customer
}
}

var john: Customer? = Customer(name: "John")
john!.card = CreditCard(number: 1234, customer: john!)

john = nil // Объект Customer и CreditCard освобождаются одновременно


🤔 Заключение

В Swift ARC управляет памятью, используя сильные, слабые и неустранимые ссылки для автоматического выделения и освобождения памяти, предотвращая утечки и циклические зависимости.

В двух фразах: Swift использует ARC для автоматического управления памятью с помощью подсчёта ссылок. Сильные ссылки удерживают объекты в памяти, слабые и неустранимые ссылки помогают избежать утечек и циклических зависимостей.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
🤔 Как называется механизм обработки ошибок в Swift, позволяющий при возникновении ошибки выйти из текущего контекста и передать управление обработчику ошибок?
Anonymous Quiz
2%
Delegates
31%
Error Handling
66%
Try-Catch
1%
Optionals
1👍1
📌 Когда value типы могут стать reference?

💬 Спрашивают в 18% собеседований

В Swift value типы (структуры и перечисления) обычно хранятся в стеке, что обеспечивает их высокую производительность. Однако в некоторых случаях value типы могут стать reference, то есть храниться в куче. Это происходит в следующих ситуациях:

1️⃣ Захват в замыкании (Closure Capture)

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

🤔 Пример:
struct MyStruct {
var value: Int
}

func createClosure() -> () -> Int {
let myStruct = MyStruct(value: 42)
return { myStruct.value }
}

let closure = createClosure()
print(closure()) // Output: 42


В этом примере myStruct захватывается замыканием, что приводит к его размещению в куче.

2️⃣ Использование класса-контейнера (Boxing)
Когда value тип заворачивается в объект класса, он хранится в куче.

🤔 Пример:
class Box<T> {
var value: T
init(_ value: T) {
self.value = value
}
}

struct MyStruct {
var value: Int
}

let boxedStruct = Box(MyStruct(value: 42))
print(boxedStruct.value.value) // Output: 42


В этом примере структура MyStruct обернута в объект класса Box, что приводит к её размещению в куче.

3️⃣ Свойства классов

Когда value тип используется в качестве свойства класса, он будет храниться в куче вместе с экземпляром класса.

🤔 Пример:
struct MyStruct {
var value: Int
}

class MyClass {
var myStruct: MyStruct
init(myStruct: MyStruct) {
self.myStruct = myStruct
}
}

let instance = MyClass(myStruct: MyStruct(value: 42))
// instance.myStruct хранится в куче


В этом примере структура MyStruct является свойством класса MyClass, поэтому её экземпляры хранятся в куче вместе с экземплярами MyClass.

4️⃣ Коллекции, содержащие value типы

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

🤔 Пример:
struct MyStruct {
var value: Int
}

let array = [MyStruct(value: 1), MyStruct(value: 2), MyStruct(value: 3)]
// Элементы массива могут быть размещены в куче


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

🤔 Заключение

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

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥3👍1
🤔 Какой протокол необходимо использовать для реализации асинхронных последовательностей в Swift?
Anonymous Quiz
5%
Codable
18%
Sequence
73%
AsyncSequence
4%
IteratorProtocol
👍2
📌 Что такое UIResponder?

💬 Спрашивают в 18% собеседований

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

🤔 Основные особенности

1️⃣ Обработка событий:

Объекты, унаследованные от UIResponder, могут обрабатывать различные события через методы, такие как touchesBegan, touchesMoved, touchesEnded и touchesCancelled.

2️⃣ Цепочка ответчиков:

Определяет, как события передаются между объектами, гарантируя, что все события будут обработаны.

🤔 Классы-наследники

UIView: Обрабатывает пользовательский интерфейс и взаимодействие.

UIViewController: Управляет экраном или его частью.

UIApplication: Управляет жизненным циклом приложения.

UIWindow: Контейнер для представлений и контроллеров.

🤔 Пример использования
class CustomView: UIView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
print("Touches began")
}
}


🤔 Заключение

UIResponder — это ключевой класс для обработки событий в iOS, предоставляющий методы для работы с касаниями и другими взаимодействиями пользователя.

В двух фразах: UIResponder обрабатывает события в iOS и управляет цепочкой ответчиков. Он является базовым классом для таких объектов, как UIView и UIViewController, обеспечивая их способность реагировать на события.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍4
🤔 Как называется механизм в Swift, позволяющий передавать функции в качестве параметров или возвращать их в качестве результата?
Anonymous Quiz
92%
Замыкания
3%
Протоколы
4%
Делегаты
1%
Модули
1
🤔 Что такое Autorelease pool?

Autorelease pool — это механизм управления памятью в Objective-C и Swift, который помогает автоматизировать освобождение объектов, когда они больше не нужны. Этот механизм используется для временного хранения объектов, которым необходимо отправить сообщение release в будущем, чтобы освободить их память. Autorelease pool обеспечивает автоматическое управление памятью и предотвращает утечки памяти, особенно в случаях, когда создаётся много временных объектов.

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

🟠Работа с временными объектами: Когда вы создаёте объект, который отправляется в autorelease pool, он не освобождается сразу, а помещается в пул. Когда пул "спускается" (drains), всем объектам в пуле отправляется сообщение release.
🟠Создание и использование Autorelease pool: В Swift и Objective-C вы можете создать собственные autorelease pools для управления памятью в циклах или других местах, где создаётся много временных объектов.

Objective-C:
@autoreleasepool {
// Создание временных объектов
NSString *tempString = [[NSString alloc] initWithFormat:@"Hello, %@", @"World"];
// tempString автоматически освободится, когда пул спустится
}


Swift:
autoreleasepool {
// Создание временных объектов
let tempString = NSString(format: "Hello, %@", "World")
// tempString автоматически освободится, когда пул спустится
}


🚩Зачем нужен Autorelease pool

Управление памятью в циклах: При создании большого количества временных объектов внутри цикла autorelease pool предотвращает увеличение использования памяти.
   for i in 0..<1000 {
autoreleasepool {
let tempString = NSString(format: "Iteration %d", i)
// tempString освобождается в конце каждой итерации
}
}


Автоматическое освобождение объектов: Autorelease pool позволяет избежать явного вызова release для каждого объекта, предоставляя автоматическое управление памятью.

🚩Как работает Autorelease pool

Создание объектов: Когда объект создаётся с использованием методов, которые возвращают autoreleased объект, он добавляется в текущий autorelease pool.
   NSString *string = [NSString stringWithFormat:@"Hello, World"];


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

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤔2
🤔 В какой момент вызывается метод viewWillAppear?

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

🚩Жизненный цикл UIViewController

Загрузка представления:
🟠loadView(): Вызывается, когда представление контроллера загружается в память.
🟠viewDidLoad(): Вызывается после загрузки представления в память. Используется для первоначальной настройки представления и инициализации данных.

Перед появлением на экране: viewWillAppear(_:): Вызывается непосредственно перед тем, как представление контроллера становится видимым на экране. Это хороший момент для обновления данных и интерфейса, если они могли измениться.

Появление на экране: viewDidAppear(_:): Вызывается после того, как представление контроллера стало видимым на экране. Здесь можно запускать анимации или начинать задачи, которые должны выполняться только после того, как представление полностью отображено.

Перед исчезновением с экрана: viewWillDisappear(_:): Вызывается непосредственно перед тем, как представление контроллера исчезнет с экрана. Это подходящее место для остановки анимаций, сохранения состояния и освобождения ресурсов.

Исчезновение с экрана: viewDidDisappear(_:): Вызывается после того, как представление контроллера исчезло с экрана. Используется для выполнения действий, которые должны произойти после того, как представление перестало быть видимым.

class MyViewController: UIViewController {

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// Обновление интерфейса перед тем, как представление станет видимым
print("viewWillAppear: Представление скоро станет видимым")

// Обновление данных
updateData()
}

func updateData() {
// Логика обновления данных
}
}


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

🟠Обновление пользовательского интерфейса: Если нужно обновить элементы интерфейса, которые могут измениться с момента последнего отображения представления.
🟠Настройка данных: Если данные, отображаемые на представлении, могли измениться и их нужно обновить перед показом.
🟠Запуск анимаций: Если требуется подготовить анимации, которые начнутся, когда представление станет видимым.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
6
🤔 Какое ключевое слово используется для объявления свойств с ленивой инициализацией в Swift?
Anonymous Quiz
6%
weak
94%
lazy
0%
unowned
0%
deferred
1
🤔 Расскажи про memory managment в ios?

Управление памятью (Memory Management) в iOS включает использование автоматического подсчета ссылок (ARC) и инструментов Xcode для анализа и профилирования памяти. ARC автоматически управляет памятью, увеличивая и уменьшая счетчик ссылок на объекты. Когда объект больше не имеет сильных ссылок (strong references), он освобождается.

🚩Основные механизмы управления памятью

Automatic Reference Counting (ARC)
🟠Сильные ссылки (Strong References) удерживают объект в памяти.
🟠Лабые ссылки (Weak References) не удерживают объект в памяти и автоматически обнуляются при освобождении объекта.
🟠Неустранимые ссылки (Unowned References) предполагают, что объект всегда будет существовать до тех пор, пока существует неустранимая ссылка.
class Person {
var name: String
weak var spouse: Person?
init(name: String) {
self.name = name
}
}


🚩Инструменты для управления памятью

Xcode Instruments
🟠Leaks: Обнаружение утечек памяти.
🟠Allocations: Отслеживание распределения и использования

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Какой протокол необходимо реализовать для поддержки сопоставления шаблонов (pattern matching) в Swift?
Anonymous Quiz
41%
Equatable
39%
Comparable
12%
Hashable
7%
CaseIterable
👍1
🤔 В чем различие очередей силиал и конкарент?

Очереди (queues) в iOS и macOS используются для управления задачами в многопоточном программировании с помощью Grand Central Dispatch (GCD). Существуют два основных типа очередей: последовательные (serial) и конкурентные (concurrent). Они различаются по способу выполнения задач.

🚩Последовательные очереди (Serial Queues)

🟠Описание: Выполняют задачи одну за другой в порядке их добавления. Каждая задача начинается только после завершения предыдущей.
🟠Использование: Подходят для задач, которые должны выполняться последовательно, чтобы избежать состояния гонки (race conditions) и конфликтов доступа к ресурсам.

let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
print("Task 1")
}
serialQueue.async {
print("Task 2")
}
// Task 1 будет выполнена перед Task 2


🚩Конкурентные очереди (Concurrent Queues)

🟠Описание: Позволяют выполнять несколько задач одновременно. Задачи могут начинаться и завершаться в произвольном порядке.
🟠Использование: Подходят для задач, которые могут выполняться параллельно, такие как загрузка данных из сети или выполнение вычислений.

let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
concurrentQueue.async {
print("Task 1")
}
concurrentQueue.async {
print("Task 2")
}
// Task 1 и Task 2 могут быть выполнены одновременно


🚩Главная очередь (Main Queue)

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

DispatchQueue.main.async {
print("Update UI")
}
// Эта задача будет выполнена на главном потоке


🚩Глобальные очереди (Global Queues)

🟠Описание: Конкурентные очереди, предоставляемые системой с различными уровнями приоритета (QoS).
🟠Использование: Выполнение задач с заданным приоритетом.

DispatchQueue.global(qos: .userInitiated).async {
print("High priority task")
}
DispatchQueue.global(qos: .background).async {
print("Low priority task")
}
// Задачи будут выполнены в соответствии с их приоритетом


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
🤔 Какой оператор используется для приведения типа в Swift, при условии, что приведение может завершиться неудачно?
Anonymous Quiz
8%
as!
85%
as?
4%
as
2%
is?
👍1
🤔 Когда начинает работать динамическая диспетчеризация?

💬 Спрашивают в 18% собеседований

Динамическая диспетчеризация в Swift начинает работать, когда методы или свойства вызываются во время выполнения программы (runtime), а не на этапе компиляции. Это может быть связано с различными механизмами, включая использование @objc и динамических ключевых слов, протоколы с необязательной реализацией, и взаимодействие с Objective-C API. Давайте рассмотрим основные случаи, когда применяется динамическая диспетчеризация:

🚩Основные случаи использования динамической диспетчеризации

Использование `@objc` и динамических ключевых слов: Методы и свойства, помеченные атрибутом @objc или ключевым словом dynamic, используют динамическую диспетчеризацию через Objective-C runtime. Это позволяет изменять поведение методов в процессе выполнения, например, через механизм замен (swizzling).
import Foundation

class MyClass: NSObject {
@objc dynamic func myMethod() {
print("Original implementation")
}
}

let obj = MyClass()
obj.myMethod() // Вызов через динамическую диспетчеризацию


Протоколы с необязательной реализацией: Протоколы, объявленные с @objc, могут иметь необязательные методы, которые вызываются через динамическую диспетчеризацию. Это позволяет проверять наличие метода и вызывать его только при наличии.
@objc protocol MyProtocol {
@objc optional func optionalMethod()
}

class MyClass: NSObject, MyProtocol {
func optionalMethod() {
print("Optional method implementation")
}
}

let obj: MyProtocol = MyClass()
obj.optionalMethod?() // Вызов через динамическую диспетчеризацию


Интерактивное взаимодействие с Objective-C API: Методы, которые взаимодействуют с Objective-C API или наследуются от классов, написанных на Objective-C, используют динамическую диспетчеризацию для вызова методов через Objective-C runtime.
import UIKit

class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Этот метод вызывается через динамическую диспетчеризацию
}
}


🚩Преимущества и недостатки динамической диспетчеризации

Преимущества:
🟠Гибкость: Позволяет изменять реализацию методов во время выполнения.
🟠Совместимость: Обеспечивает взаимодействие с Objective-C кодом и библиотеками.
🟠Необязательные методы в протоколах: Упрощает работу с протоколами, где реализация методов может быть необязательной.

Недостатки:
🟠Производительность: Динамическая диспетчеризация медленнее, чем статическая, из-за необходимости поиска метода в runtime.
🟠Сложность отладки: Усложняет отладку и понимание кода, так как методы могут изменяться во время выполнения.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
🤔 Какой модификатор доступа позволяет использовать элементы только в пределах того же модуля, но не вне его?
Anonymous Quiz
3%
open
12%
public
58%
internal
27%
private
👍2