Swift | Вопросы собесов
2.13K subscribers
28 photos
937 links
Download Telegram
Как будут реализованы опциональные функции в протоколах ?
Спросят с вероятностью 18%

Для реализации опциональных функций в протоколах существуют несколько подходов. Первый подход, который уже был описан ранее, использует @objc атрибут и опциональные члены, доступные только для классов и только в контексте Objective-C совместимости. Однако, помимо этого подхода, можно использовать несколько других техник для достижения похожего результата, без использования @objc.

Реализация:

1️⃣Расширения протоколов

Методы в протоколах могут иметь реализацию по умолчанию с помощью расширений. Это позволяет объектам, подписанным под протокол, не реализовывать эти методы, так как уже существует базовая реализация.
protocol MyProtocol {
func requiredMethod()
func optionalMethod()
}

extension MyProtocol {
func optionalMethod() {
print("Default implementation of optionalMethod")
}
}

class MyClass: MyProtocol {
func requiredMethod() {
print("Implementation of requiredMethod")
}
}

let instance = MyClass()
instance.requiredMethod() // Вывод: "Implementation of requiredMethod"
instance.optionalMethod() // Вывод: "Default implementation of optionalMethod"


2️⃣Использование пустых реализаций

Можно определить методы в протоколе как требуемые, но предоставить пустую реализацию в расширении протокола. Это дает возможность типам не предоставлять собственные реализации.
protocol MyProtocol {
func requiredMethod()
func optionalMethod()
}

extension MyProtocol {
func optionalMethod() {}
}

class MyClass: MyProtocol {
func requiredMethod() {
print("Implementation of requiredMethod")
}
}

let instance = MyClass()
instance.requiredMethod() // Вывод: "Implementation of requiredMethod"
instance.optionalMethod() // Ничего не выводится


Особенности:

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

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍1
🤔 Какой метод протокола Equatable требуется для сравнения экземпляров в Swift?
Anonymous Quiz
16%
isEqualTo()
13%
equals()
65%
==
5%
compare()
👍1
Могут ли быть в протоколах опциональные функции ?
Спросят с вероятностью 18%

Протоколы могут содержать опциональные функции, но для этого требуется использование @objc атрибута. Этот атрибут указывает, что протокол и его опциональные члены должны быть доступны в Objective-C, что добавляет некоторые ограничения.

Особенности:

1️⃣Использование `@objc`: Протокол должен быть объявлен с атрибутом @objc для того, чтобы поддерживать опциональные члены. Это делает протокол совместимым с Objective-C.

2️⃣Ограничение на типы: Только классы могут реализовывать такие протоколы с опциональными функциями, так как @objc протоколы не могут быть приняты структурами или перечислениями.

3️⃣Синтаксис: Опциональные методы в протоколе должны быть явно помечены как optional.
import Foundation

@objc protocol MyProtocol {
@objc optional func optionalMethod()
func requiredMethod()
}

class MyClass: MyProtocol {
func requiredMethod() {
print("Реализация обязательного метода")
}

func optionalMethod() {
print("Реализация опционального метода")
}
}

class MySecondClass: MyProtocol {
func requiredMethod() {
print("Реализация обязательного метода во втором классе")
}
// Опциональный метод не реализован
}

let myObject = MyClass()
myObject.optionalMethod?() // Вывод: "Реализация опционального метода"
myObject.requiredMethod() // Вывод: "Реализация обязательного метода"

let mySecondObject = MySecondClass()
mySecondObject.optionalMethod?() // Ничего не происходит, метод не вызывается
mySecondObject.requiredMethod() // Вывод: "Реализация обязательного метода во втором классе"


В этом примере MyClass реализует как опциональный, так и обязательный методы, тогда как MySecondClass реализует только обязательный метод. Вызов optionalMethod происходит с использованием синтаксиса опционального вызова (?()), что безопасно, даже если метод не реализован.
Альтернативы:

Если вы хотите избежать использования @objc и Objective-C совместимости, вы можете рассмотреть другие подходы, такие как:

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

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

Эти методы позволяют достичь похожей гибкости без необходимости совместимости с Objective-C.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍4
Что используется для многопоточности в IOS ?
Спросят с вероятностью 27%

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

1️⃣Grand Central Dispatch (GCD)
Это низкоуровневый API для многозадачности, основанный на очередях. GCD позволяет выполнять задачи асинхронно или синхронно в различных очередях. Очереди могут быть последовательными (serial) или параллельными (concurrent). GCD автоматически управляет пулом потоков, что упрощает работу с многопоточностью.
DispatchQueue.global(qos: .background).async {
// Выполнить тяжёлую операцию в фоновом потоке
let result = performHeavyComputation()
DispatchQueue.main.async {
// Вернуться к главному потоку для обновления UI
self.updateUI(with: result)
}
}


2️⃣Operation и OperationQueue
Это абстрактный класс, который представляет собой одиночную задачу. Задачи, представленные операциями (Operation), могут быть добавлены в OperationQueue, который управляет их параллельным или последовательным выполнением. Operation и OperationQueue предоставляют больше контроля и гибкости по сравнению с GCD, позволяя устанавливать зависимости между операциями, приостанавливать и возобновлять их выполнение.
let operationQueue = OperationQueue()

let operation1 = BlockOperation {
// Выполнить задачу 1
}

let operation2 = BlockOperation {
// Выполнить задачу 2
}

operation2.addDependency(operation1) // Задача 2 не начнется, пока не завершится задача 1
operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)


3️⃣async/await (Swift 5.5 и выше)
async/await упрощает асинхронное программирование, делая асинхронный код более читабельным и похожим на синхронный. Это существенно упрощает работу с асинхронными операциями, такими как сетевые запросы или долгие вычисления, и обеспечивает более безопасное и удобное управление потоками.
func fetchData() async throws -> Data {
let url = URL(string: "https://example.com/data")!
let (data, _) = try await URLSession.shared.data(from: url)
return data
}

// Где-то в асинхронном контексте
Task {
do {
let data = try await fetchData()
// Обработка данных
} catch {
// Обработка ошибки
}
}


Для реализации многопоточности применяются Grand Central Dispatch (GCD), Operation и OperationQueue для управления асинхронными операциями и параллельным выполнением задач. С появлением Swift 5.5 добавился новый удобный способ работы с асинхронностью через async/await, который делает код более читабельным и упрощает работу с асинхронными операциями.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Можно ли добавить структуру в extension ?
Спросят с вероятностью 18%

Можно использовать расширения (extensions) для добавления новой функциональности к существующим типам, включая классы, структуры, перечисления и даже протоколы. Расширения позволяют добавлять новые методы, вычисляемые свойства, инициализаторы, сабскрипты, вложенные типы и протоколы к существующим типам. Однако, есть ограничения на то, что можно добавить через расширения.

Что можно добавить через него:
1️⃣Методы экземпляра и типа
2️⃣Вычисляемые свойства экземпляра и типа
3️⃣Новые инициализаторы (только для структур и классов в том же файле)
4️⃣Определения протоколов
5️⃣Вложенные типы

Что нельзя добавить через него:
Хранимые свойства
Свойства свойства наблюдателя

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

Расширение структуры с новым методом:
struct Point {
var x: Int
var y: Int
}

extension Point {
func isToTheRightOf(x: Int) -> Bool {
return self.x > x
}
}

let somePoint = Point(x: 10, y: 5)
print(somePoint.isToTheRightOf(x: 4)) // Вывод: true


Добавление вычисляемого свойства:
extension Point {
var isOrigin: Bool {
return x == 0 && y == 0
}
}

let originPoint = Point(x: 0, y: 0)
print(originPoint.isOrigin) // Вывод: true


Добавление нового инициализатора (только в том же файле для классов, для структур такое ограничение отсутствует):
extension Point {
init() {
self.init(x: 0, y: 0)
}
}

let defaultPoint = Point()
print(defaultPoint) // Вывод: Point(x: 0, y: 0)


Ответ на ваш вопрос
Можно определить вложенный тип внутри расширения.

Пример:
extension Array where Element: Numeric {
struct Summary {
var total: Element
var count: Int
}

var summary: Summary {
return Summary(total: self.reduce(0, +), count: self.count)
}
}

let numbers = [1, 2, 3, 4, 5]
let numbersSummary = numbers.summary
print("Total: \(numbersSummary.total), Count: \(numbersSummary.count)") // Вывод: Total: 15, Count: 5


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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍1
🤔 Какое свойство в Swift используется для хранения данных, которые не должны сериализоваться при кодировании?
Anonymous Quiz
45%
lazy
12%
weak
31%
transient
12%
volatile
Можно ли добавить структуру в extension ?
Спросят с вероятностью 18%

Можно использовать расширения (extensions) для добавления новой функциональности к существующим типам, включая классы, структуры, перечисления и даже протоколы. Расширения позволяют добавлять новые методы, вычисляемые свойства, инициализаторы, сабскрипты, вложенные типы и протоколы к существующим типам. Однако, есть ограничения на то, что можно добавить через расширения.

Что можно добавить через него:
1️⃣Методы экземпляра и типа
2️⃣Вычисляемые свойства экземпляра и типа
3️⃣Новые инициализаторы (только для структур и классов в том же файле)
4️⃣Определения протоколов
5️⃣Вложенные типы

Что нельзя добавить через него:
Хранимые свойства
Свойства свойства наблюдателя

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

Расширение структуры с новым методом:
struct Point {
var x: Int
var y: Int
}

extension Point {
func isToTheRightOf(x: Int) -> Bool {
return self.x > x
}
}

let somePoint = Point(x: 10, y: 5)
print(somePoint.isToTheRightOf(x: 4)) // Вывод: true


Добавление вычисляемого свойства:
extension Point {
var isOrigin: Bool {
return x == 0 && y == 0
}
}

let originPoint = Point(x: 0, y: 0)
print(originPoint.isOrigin) // Вывод: true


Добавление нового инициализатора (только в том же файле для классов, для структур такое ограничение отсутствует):
extension Point {
init() {
self.init(x: 0, y: 0)
}
}

let defaultPoint = Point()
print(defaultPoint) // Вывод: Point(x: 0, y: 0)


Ответ на ваш вопрос
Можно определить вложенный тип внутри расширения.

Пример:
extension Array where Element: Numeric {
struct Summary {
var total: Element
var count: Int
}

var summary: Summary {
return Summary(total: self.reduce(0, +), count: self.count)
}
}

let numbers = [1, 2, 3, 4, 5]
let numbersSummary = numbers.summary
print("Total: \(numbersSummary.total), Count: \(numbersSummary.count)") // Вывод: Total: 15, Count: 5


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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👀1
Какие можно выделить главные принципы ООП ?
Спросят с вероятностью 27%

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

1️⃣Инкапсуляция
Механизм ООП, который объединяет данные (атрибуты) и код (методы), манипулирующий этими данными, внутри одного объекта и скрывает детали реализации от внешнего использования. Это позволяет защитить внутреннее состояние объекта от прямого доступа извне и обеспечить контролируемый интерфейс для работы с этим объектом.

2️⃣Наследование
Позволяет создавать новый класс на основе уже существующего класса, перенимая его свойства и методы. Новый класс может добавлять собственные свойства и методы или модифицировать унаследованные. Наследование обеспечивает повторное использование кода, упрощает его расширение и поддержку.

3️⃣Полиморфизм
Способность объектов с одинаковым интерфейсом предоставлять различную реализацию для одного и того же метода. Это означает, что функция или метод могут использоваться для различных типов объектов, и каждый тип может реализовать эту функцию или метод по-своему. Полиморфизм упрощает написание общего кода для работы с объектами разных классов и обеспечивает гибкость в его использовании.

4️⃣Абстракция
Позволяет скрыть сложность системы, представляя её ключевые аспекты и скрывая детали реализации. Это достигается за счёт использования абстрактных классов и интерфейсов, которые определяют шаблон для классов-наследников. Абстракция помогает сосредоточиться на взаимодействии объектов на более высоком уровне, игнорируя ненужные детали.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
🤔 Вопрос: Какой метод в Swift используется для вывода данных в консоль?
Anonymous Quiz
93%
print()
2%
echo()
3%
log()
2%
output
Inam относится ли к value тайпам ?
Спросят с вероятностью 18%

enum (перечисления) относится к типам значений (value types). Это означает, что при передаче перечисления функции или при его присвоении переменной создается новая копия этого перечисления. Это работает аналогично другим типам значений, таким как struct и базовые типы данных (Int, String, Double и т.д.).

Особенности:

1️⃣Копирование при присвоении: Когда переменной перечисления присваивается значение другой переменной перечисления, создается независимая копия этого значения.

2️⃣Безопасность типов: enum поддерживает безопасность типов, что позволяет создавать код, легкий для понимания и поддержки.

3️⃣Связанные значения: enum может хранить связанные значения различных типов. Например:
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}



В этом примере Barcode может хранить либо UPC с четырьмя числовыми значениями, либо QR-код в виде строки.

4️⃣Методы: enum может иметь методы, которые предоставляют функциональность, связанную с перечислением.
enum Planet {
case earth, mars, venus

func isHabitable() -> Bool {
switch self {
case .earth:
return true
default:
return false
}
}
}



Здесь метод isHabitable позволяет определить, пригодна ли планета для жизни.

Пример:
enum TrafficLight {
case red, yellow, green
}

var light = TrafficLight.red
var lightCopy = light
lightCopy = .green

print(light) // Выводит "red"
print(lightCopy) // Выводит "green"


Когда lightCopy изменяется, это не влияет на исходное значение light, что демонстрирует поведение типа значения.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
🤯3👍1🤔1
Какой тип коллекций в Swift'е: value или reference ?
Спросят с вероятностью 27%

Коллекции, такие как массивы (Array), словари (Dictionary) и множества (Set), реализованы как структуры, что означает, что они являются типами значений (value types). Это имеет важные последствия для работы с коллекциями в Swift.

Типы значений (Value Types)

Когда вы работаете с ними, любые изменения, вносимые в переменную или константу, не влияют на исходный экземпляр, с которым они были скопированы. В контексте коллекций это значит, что при копировании массива, словаря или множества создаётся новая, независимая копия этих данных. Рассмотрим пример с массивом:
var originalArray = [1, 2, 3]
var copiedArray = originalArray // Копия originalArray
copiedArray.append(4) // Изменение copiedArray

print(originalArray) // Выводит [1, 2, 3]
print(copiedArray) // Выводит [1, 2, 3, 4]


В этом примере изменения copiedArray не влияют на originalArray благодаря механизму копирования при записи (Copy-On-Write, COW). Этот механизм оптимизирует работу с памятью, копируя данные только в момент их изменения.

Зачем они нужны?

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

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Что такое hip object ?
Спросят с вероятностью 18%

Термин "hip object" может вызвать некоторое недоумение, так как он не является стандартным термином. Однако, если рассматривать контекст вопроса, возможно, произошла опечатка или недоразумение, и имелся в виду термин "heap object".

Что это такое?

Объекты на куче (heap objects) — это объекты, для которых память выделяется в области памяти, известной как "куча" (heap). Во многих языках куча используется для динамического выделения памяти во время выполнения программы.

Особенности:

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

2️⃣Управление памятью: В языках с автоматическим управлением памятью, таких как Java или Python, сборщик мусора автоматически освобождает память, занятую объектами, которые больше не используются. В языках, требующих явного управления памятью, таких как C или C++, программист должен самостоятельно освобождать память, выделенную для объектов на куче.

3️⃣Время жизни: Объекты на куче могут сохраняться в памяти в течение всего времени выполнения программы, если не будет явно освобождена память, которую они занимают. Это отличает их от объектов, размещенных на стеке, время жизни которых ограничено временем жизни вызова функции, в которой они были созданы.

4️⃣Доступ: Доступ к объектам на куче обычно осуществляется через указатели или ссылки, так как их точное местоположение в памяти не известно во время компиляции и определяется во время выполнения.

Если в вашем вопросе действительно имелся в виду "heap object", то объяснение выше должно дать полное представление об этом понятии. Если же "hip object" означает что-то иное в специфическом контексте или технологии, уточните, пожалуйста, контекст или область применения, чтобы я мог предоставить более точный ответ.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
😁7👍21
🤔 Какой механизм в Swift предотвращает доступ к переменной из разных потоков одновременно для предотвращения состояния гонки?
Anonymous Quiz
49%
Dispatch Semaphores
22%
Dispatch Queue
19%
Synchronous Lock
10%
Atomic Operations
Что такое deadlock ?
Спросят с вероятностью 27%

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

Как он возникает

Для его возникновения обычно должны быть выполнены четыре условия, называемые условиями Коффмана:
1️⃣Взаимное исключение — только один процесс может использовать ресурс в данный момент времени.
2️⃣Удержание и ожидание — процессы, удерживающие ресурсы, могут запрашивать новые ресурсы.
3️⃣Отсутствие прерывания — ресурсы не могут быть принудительно изъяты у процессов; процесс сам должен освободить ресурс.
4️⃣Циклическое ожидание — существует цикл в графе ожидания ресурсов, где каждый процесс дополнительно ожидает ресурс, занятый следующим в цикле.

Пример, который может привести к deadlock в многопоточном приложении:
var lockA = NSLock()
var lockB = NSLock()

func thread1() {
lockA.lock()
print("Thread 1 locked A")
sleep(1) // Даем время другому потоку захватить lockB
lockB.lock()
print("Thread 1 locked B")
lockB.unlock()
lockA.unlock()
}

func thread2() {
lockB.lock()
print("Thread 2 locked B")
sleep(1) // Даем время первому потоку захватить lockA
lockA.lock()
print("Thread 2 locked A")
lockA.unlock()
lockB.unlock()
}

DispatchQueue.global().async(execute: thread1)
DispatchQueue.global().async(execute: thread2)


В этом примере thread1 и thread2 запускаются параллельно и пытаются получить два замка (lockA и lockB). Однако из-за временной задержки (sleep) каждый поток успевает захватить один замок и ожидает освобождения второго, который держит другой поток. Это ведет к взаимной блокировке.

Чтобы избежать deadlock, можно:
Использовать тайм-ауты при попытках захвата замков.
Убедиться, что все потоки захватывают замки в одном и том же порядке.
Использовать алгоритмы обнаружения deadlock и соответствующие стратегии восстановления.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
2
🤔 Какая функция Swift позволяет выполнить код асинхронно на заданной очереди?
Anonymous Quiz
30%
asyncAfter
2%
performSelector
0%
NSTimer.scheduledTimer
Какая ссылка производительнее: unowed или weak ?
Спросят с вероятностью 18%

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

Сравнение weak и unowned

1️⃣`weak`
Используются, когда один объект может существовать без другого. weak ссылка всегда является опциональной, и автоматически становится nil, когда объект, на который она указывает, уничтожается. Это делает weak ссылки безопасными с точки зрения времени выполнения, так как они явно показывают, что объект может отсутствовать.
Пример: В UI программировании ссылка на делегат обычно объявляется как weak, потому что делегат может быть освобожден в любой момент, и необязательно должен существовать весь жизненный цикл объекта, держащего ссылку.

2️⃣`unowned`
Используются, когда один объект всегда должен существовать, пока существует другой объект, указывающий на него. В отличие от weak, unowned ссылка не является опциональной и не обнуляется автоматически. Если вы попытаетесь получить доступ к unowned ссылке после того, как объект был уничтожен, это приведёт к ошибке времени выполнения (runtime crash).
Пример: Если у вас есть класс, который гарантированно не будет использоваться после уничтожения своего владельца, то unowned может быть более подходящим выбором.

Производительность

unowned ссылки могут быть чуть более эффективными, поскольку они не требуют проверки на nil, что необходимо делать при каждом доступе к weak ссылке. Такие ссылки просто предполагают, что объект всегда существует, в то время как weak ссылки могут потребовать дополнительных операций для обработки случая, когда объект уже был уничтожен.

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

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍2
📌 Какие виды диспетчеризации существуют в свифт?

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

В Swift существует несколько видов диспетчеризации, которые определяют, как и когда вызываются методы или функции. Основные виды диспетчеризации включают статическую диспетчеризацию (static dispatch), диспетчеризацию по таблице виртуальных функций (vtable dispatch), диспетчеризацию по свидетелю (witness table dispatch) и динамическую диспетчеризацию (dynamic dispatch). Рассмотрим их подробнее:

1️⃣ Статическая диспетчеризация (Static Dispatch)
Описание: Вызов функции или метода определяется на этапе компиляции. Используется для функций и методов, которые не переопределяются в подклассах или не являются динамическими.

Использование: Для структур, перечислений и final классов.

Пример:
     struct MyStruct {
func printMessage() {
print("Hello from MyStruct")
}
}

let instance = MyStruct()
instance.printMessage() // Вызов определяется на этапе компиляции


2️⃣ Диспетчеризация по таблице виртуальных функций (Vtable Dispatch)
Описание: Используется для вызова методов класса, которые могут быть переопределены в подклассах. Виртуальная таблица (vtable) используется для определения, какой метод вызывать.

Использование: Для классов и их подклассов.

Пример:
     class BaseClass {
func printMessage() {
print("Hello from BaseClass")
}
}

class SubClass: BaseClass {
override func printMessage() {
print("Hello from SubClass")
}
}

let instance: BaseClass = SubClass()
instance.printMessage() // Вызов определяется в runtime с использованием vtable


3️⃣ Диспетчеризация по свидетелю (Witness Table Dispatch)
Описание: Используется для вызова методов протоколов, реализованных типами. Таблица свидетелей (witness table) используется для определения, какой метод вызывать.

Использование: Для типов, соответствующих протоколам.

Пример:
     protocol MyProtocol {
func printMessage()
}

struct MyStruct: MyProtocol {
func printMessage() {
print("Hello from MyStruct")
}
}

let instance: MyProtocol = MyStruct()
instance.printMessage() // Вызов определяется в runtime с использованием witness table


4️⃣ Динамическая диспетчеризация (Dynamic Dispatch)
Описание: Используется для вызова методов, отмеченных как dynamic или методов Objective-C. Метод определяется в runtime с использованием Objective-C runtime.

Использование: Для методов, которые должны быть динамически разрешены в runtime, обычно для взаимодействия с Objective-C.

Пример:
     import Foundation

class MyClass: NSObject {
@objc dynamic func printMessage() {
print("Hello from MyClass")
}
}

let instance = MyClass()
instance.printMessage() // Вызов определяется в runtime с использованием Objective-C runtime


🤔 Заключение

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

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

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

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
Кто последний может обработать кнопку в иерархией вьюшек ?
Спросят с вероятностью 18%

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

Понимание Responder Chain
В UIKit все представления (views) и контроллеры (view controllers) являются частью так называемой цепочки обработчиков (responder chain), которая определяет, как объекты в приложении реагируют на события пользовательского ввода, такие как касания, жесты или движения. Цепочка респондеров следует по иерархии представлений от первого респондера к следующим объектам в иерархии, пока событие не будет обработано или пока не будут исчерпаны все возможные респондеры.

Как она проходит
1️⃣Начальная точка: Обычно, когда происходит нажатие на кнопку, система сначала пытается определить, какой view в иерархии непосредственно получил касание. Это view становится первым респондером для события.

2️⃣Восходящая передача: Если view (или кнопка) решает, что она не будет обрабатывать событие, событие передается его родительскому view. Этот процесс продолжается вверх по иерархии view, пока не будет найден подходящий обработчик или пока событие не достигнет корневого view.

3️⃣Контроллеры представления: Если ни один из view не обработал событие, событие передается контроллеру представления, который управляет текущим view.

4️⃣Дополнительные обработчики: Если контроллер представления также не обрабатывает событие, оно может быть передано дальше другим контроллерам или объектам, таким как UIWindow или UIApplication, и, в конечном счете, AppDelegate.

Исключительная ситуация

Однако, если какой-то из объектов в цепочке респондеров переопределяет метод обработки и возвращает, что он обработал событие, обработка события прекращается, и оно не распространяется дальше по цепочке.

Если никакой из view или контроллеров в иерархии не обработает событие, последними потенциальными обработчиками будут объекты на уровне приложения, такие как UIWindow или UIApplication, и в крайнем случае AppDelegate. В стандартной ситуации обычно ожидается, что событие будет обработано на уровне view или контроллера представления, но возможность распространения до самого верха существует.

👉 Можно посмотреть примеры как отвечают люди на этот вопрос, или перейти к списку 823 вопросов на IOS разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
1👍1
🤔 Какая функциональность Swift позволяет выполнить блок кода и гарантировать его завершение даже в случае ошибки или исключения?
Anonymous Quiz
57%
defer
29%
guard
9%
finally
5%
ensure