Swift | Вопросы собесов
2.13K subscribers
28 photos
949 links
Download Telegram
🤔 Как расшифровывается СA?

Расшифровывается как Core Animation. Это фреймворк, используемый в iOS и macOS для создания анимаций. Core Animation предоставляет высокоуровневый API для работы с анимациями, которые могут быть применены к слоям (CALayer). Он позволяет разработчикам создавать плавные и эффективные анимации с минимальными усилиями.

🚩Возможности

🟠Основные анимации (CABasicAnimation)
Анимация изменения свойств слоя, таких как позиция, масштаб, поворот, прозрачность и т.д.
🟠Ключевые кадры (CAKeyframeAnimation)
Создание сложных анимаций с использованием ключевых кадров, позволяющих анимировать свойства слоя по нескольким значениям.
🟠Групповые анимации (CAAnimationGroup)
Одновременное выполнение нескольких анимаций, объединенных в одну группу.
🟠Переходы (CATransition)
Анимация переходов между состояниями слоев, таких как изменение содержимого или структуры слоя.
🟠Слоистая модель (CALayer)
Core Animation основывается на слоях (CALayer), которые представляют собой абстракцию для управления графическим содержимым и анимациями.

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

Основная анимация (CABasicAnimation)
import UIKit

class AnimationViewController: UIViewController {
let animatedLayer = CALayer()

override func viewDidLoad() {
super.viewDidLoad()

// Настройка слоя
animatedLayer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
animatedLayer.backgroundColor = UIColor.blue.cgColor
self.view.layer.addSublayer(animatedLayer)

// Создание анимации перемещения
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = CGPoint(x: 50, y: 50)
animation.toValue = CGPoint(x: 300, y: 300)
animation.duration = 2.0

// Добавление анимации к слою
animatedLayer.add(animation, forKey: "positionAnimation")

// Обновление конечного состояния слоя
animatedLayer.position = CGPoint(x: 300, y: 300)
}
}


CAKeyframeAnimation
import UIKit

class KeyframeAnimationViewController: UIViewController {
let animatedLayer = CALayer()

override func viewDidLoad() {
super.viewDidLoad()

// Настройка слоя
animatedLayer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
animatedLayer.backgroundColor = UIColor.red.cgColor
self.view.layer.addSublayer(animatedLayer)

// Создание анимации ключевых кадров
let keyframeAnimation = CAKeyframeAnimation(keyPath: "position")
keyframeAnimation.values = [
CGPoint(x: 50, y: 50),
CGPoint(x: 150, y: 150),
CGPoint(x: 250, y: 50),
CGPoint(x: 300, y: 300)
]
keyframeAnimation.duration = 4.0

// Добавление анимации к слою
animatedLayer.add(keyframeAnimation, forKey: "positionKeyframeAnimation")

// Обновление конечного состояния слоя
animatedLayer.position = CGPoint(x: 300, y: 300)
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
3😁1
🤔 Что такое синхронная задача?

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

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

Это высокоуровневый механизм синхронизации, который объединяет взаимное исключение (mutex) и условные переменные (condition variables) для управления доступом к объектам в многопоточной среде.

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

🟠Взаимное исключение (Mutual Exclusion)
Только один поток может выполнить защищенный блок кода в любой момент времени.
🟠Условные переменные (Condition Variables)
Позволяют потокам ожидать определенных условий, а другим потокам уведомлять их о наступлении этих условий.

🚩Примеры

class ThreadSafeClass {
private var internalState = 0
private let queue = DispatchQueue(label: "com.example.threadSafeQueue")

func increment() {
queue.sync {
internalState += 1
}
}

func getState() -> Int {
return queue.sync {
internalState
}
}
}


С NSLock
class ThreadSafeClass {
private var internalState = 0
private let lock = NSLock()

func increment() {
lock.lock()
internalState += 1
lock.unlock()
}

func getState() -> Int {
lock.lock()
let state = internalState
lock.unlock()
return state
}
}


С objc_sync_enter и objc_sync_exit
class ThreadSafeClass: NSObject {
private var internalState = 0

func increment() {
objc_sync_enter(self)
internalState += 1
objc_sync_exit(self)
}

func getState() -> Int {
objc_sync_enter(self)
let state = internalState
objc_sync_exit(self)
return state
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 В чем разница между open и public в Swift?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3
🤔 Можем ли на переменную "повесить" Synchronized?

В отличие от некоторых других языков, таких как Java, нет прямого способа "повесить" синхронизацию на отдельную переменную с использованием ключевого слова synchronized. Вместо этого, синхронизация осуществляется на уровне методов или блоков кода, которые обращаются к переменной. Это достигается использованием механизмов синхронизации, таких как NSLock, DispatchQueue, или атомарные переменные.

🚩Примеры

🟠C `NSLock`
В данном примере, доступ к переменной _value синхронизирован с помощью NSLock, что предотвращает одновременное чтение и запись из нескольких потоков.
class ThreadSafeVariable {
private var _value: Int = 0
private let lock = NSLock()

var value: Int {
get {
lock.lock()
let v = _value
lock.unlock()
return v
}
set {
lock.lock()
_value = newValue
lock.unlock()
}
}
}


🟠C `DispatchQueue`
В этом примере, доступ к переменной _value осуществляется через серийную очередь, что обеспечивает эксклюзивный доступ к переменной в любой момент времени.
class ThreadSafeVariable {
private var _value: Int = 0
private let queue = DispatchQueue(label: "com.example.threadSafeQueue")

var value: Int {
get {
return queue.sync {
_value
}
}
set {
queue.sync {
_value = newValue
}
}
}
}



🚩C использованием атомарных переменных
Здесь используется атомарная переменная ManagedAtomic для обеспечения безопасного доступа к переменной _value.
import Atomics

class ThreadSafeVariable {
private var _value = ManagedAtomic(0)

var value: Int {
get {
return _value.load(ordering: .relaxed)
}
set {
_value.store(newValue, ordering: .relaxed)
}
}
}


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

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

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

Это базовое понятие в объектно-ориентированном программировании (ООП). Это экземпляр класса, который может содержать данные и методы для работы с этими данными. В Swift, как и в большинстве ООП-языков, объекты играют ключевую роль в организации и структурировании кода.

🚩Характеристики

🟠Состояние (State)
Представлено данными или свойствами (properties) объекта. Например, объект Car может иметь свойства color, model, и year.
🟠Поведение (Behavior)
Определяется методами (methods) объекта. Например, объект Car может иметь методы drive() и brake().
🟠Идентичность (Identity)
Каждый объект имеет уникальную идентичность, которая отличает его от других объектов, даже если их состояния идентичны.

🚩Объекты и классы

Это шаблон или чертеж для создания объектов. Он определяет свойства и методы, которые будут у объектов данного класса. Объект является экземпляром класса.
class Car {
var color: String
var model: String
var year: Int

init(color: String, model: String, year: Int) {
self.color = color
self.model = model
self.year = year
}

func drive() {
print("The \(color) \(model) is driving.")
}

func brake() {
print("The \(color) \(model) is braking.")
}
}


Создание объекта:
let myCar = Car(color: "Red", model: "Toyota", year: 2020)
myCar.drive()
myCar.brake()


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

🟠Инкапсуляция (Encapsulation)
Объекты скрывают детали реализации и предоставляют интерфейс для взаимодействия. Это способствует защите данных и улучшению модульности.
🟠Наследование (Inheritance)
Объекты могут наследовать свойства и методы от других классов, позволяя создавать иерархии классов и повторно использовать код.
🟠Полиморфизм (Polymorphism)
Объекты могут быть обработаны через интерфейсы или базовые классы, что позволяет использовать один и тот же код для объектов разных типов.

🚩Пример инкапсуляции

В этом примере, свойство age скрыто от внешнего доступа, и доступ к нему осуществляется через методы getAge и setAge.
class Person {
private var age: Int

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

func getAge() -> Int {
return age
}

func setAge(newAge: Int) {
if newAge > 0 {
age = newAge
}
}
}

let person = Person(age: 25)
print(person.getAge()) // 25
person.setAge(newAge: 30)
print(person.getAge()) // 30


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

Основные принципы объектно-ориентированного программирования (ООП) включают:
1. Инкапсуляция: сокрытие внутренних деталей реализации объекта и объединение данных и методов, работающих с этими данными, в один объект.
2. Наследование: создание нового класса на основе существующего.
3. Полиморфизм: возможность обращаться с объектами, производными от одного базового класса, для выполнения методов, определенных в базовом классе, но переопределенных в производных.
4. Абстракция: определение интерфейса взаимодействия с объектом, отделяющего его функциональное поведение от конкретной реализации.

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

Объект создается в момент инициализации экземпляра класса. В языке Swift это происходит при вызове конструктора (initializer) класса с использованием ключевого слова init. Когда инициализатор вызывается, выделяется память для объекта, и его свойства устанавливаются значениями, указанными в инициализаторе.

🚩Процесс создания объекта

1⃣Выделение памяти
Память для нового объекта выделяется в heap (куче).
2⃣Инициализация свойств
Все свойства объекта инициализируются значениями, указанными в конструкторе.
3⃣Вызов конструктора
Конструктор устанавливает начальное состояние объекта.

🚩Пример

class Car {
var color: String
var model: String
var year: Int

init(color: String, model: String, year: Int) {
self.color = color
self.model = model
self.year = year
}

func drive() {
print("The \(color) \(model) is driving.")
}

func brake() {
print("The \(color) \(model) is braking.")
}
}


🚩Создание объекта

let myCar = Car(color: "Red", model: "Toyota", year: 2020)


1⃣Выделение памяти
Память для объекта myCar выделяется в heap.
2⃣Инициализация свойств
Свойства color, model и year инициализируются значениями "Red", "Toyota" и 2020 соответственно.
3⃣Вызов конструктора
Инициализатор init(color:model:year:) устанавливает эти значения.

🚩Виды инициализаторов

🟠Назначенные инициализаторы (Designated Initializers)
Основные инициализаторы, которые инициализируют все свойства объекта.
🟠Удобные инициализаторы (Convenience Initializers)
Вспомогательные инициализаторы, которые вызывают другой инициализатор и могут задавать дополнительные параметры.
class Car {
var color: String
var model: String
var year: Int

init(color: String, model: String, year: Int) {
self.color = color
self.model = model
self.year = year
}

convenience init(model: String) {
self.init(color: "White", model: model, year: 2020)
}
}

let defaultCar = Car(model: "Honda")


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Чем отличается frame от bounds?

Frame определяет положение и размер view относительно его родительской view, используя координаты родителя. Bounds описывает размеры и положение внутренней области view, используя собственные координаты, начиная от точки (0,0).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3
Forwarded from Идущий к IT
Твое резюме на HeadHunter — ОК, если ты видишь это.

HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.

Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.

Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.

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

О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
🤔 Что такое companion object?

В языках программирования, таких как Kotlin, термин companion object используется для обозначения особого объекта, который связан с определенным классом и позволяет хранить статические члены этого класса. В Swift нет прямого аналога companion object, но схожие концепции можно реализовать с помощью статических свойств и методов.

🚩Companion Object

Используется для определения статических членов класса. Они могут быть вызваны без создания экземпляра класса.
class MyClass {
companion object {
fun staticMethod() {
println("This is a static method")
}
}
}

// Вызов метода без создания экземпляра класса
MyClass.staticMethod()


🚩Аналог в Swift

В Swift статические члены класса (свойства и методы) определяются с использованием ключевого слова static. Статические члены принадлежат самому классу, а не его экземплярам.
class MyClass {
static func staticMethod() {
print("This is a static method")
}
}

// Вызов метода без создания экземпляра класса
MyClass.staticMethod()


🚩Свойства и методы класса

Также можно использовать ключевое слово class для определения методов класса, которые могут быть переопределены в подклассах.
class MyClass {
class func classMethod() {
print("This is a class method")
}
}

class SubClass: MyClass {
override class func classMethod() {
print("This is an overridden class method")
}
}

// Вызов метода без создания экземпляра класса
MyClass.classMethod() // Output: This is a class method
SubClass.classMethod() // Output: This is an overridden class method


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 В чем разница между MVC и MVVM

MVC (Model-View-Controller) и MVVM (Model-View-ViewModel) — это архитектурные шаблоны для организации кода, но они различаются подходом к связи компонентов. В MVC контроллер управляет взаимодействием между моделью и представлением, а представление напрямую зависит от контроллера, что упрощает структуру, но может усложнять тестирование. В MVVM модель представления (ViewModel) связывается с представлением через механизм привязки данных, что делает его более удобным для двусторонней связи и улучшает тестируемость и поддерживаемость, особенно в приложениях с пользовательским интерфейсом, например, на Android или WPF.

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

🚩Обычный объект внутри класса

Когда вы добавляете обычный объект внутри класса, вы создаете именованный объект, который является экземпляром анонимного класса. Он может содержать свойства и методы, и он создается один раз при создании экземпляра внешнего класса.
class MyClass {
let instanceProperty = "Instance Property"

struct MyObject {
static let objectProperty = "Object Property"

static func objectMethod() {
print("This is an object method")
}
}
}

// Использование
let myClassInstance = MyClass()
print(MyClass.MyObject.objectProperty) // Доступ к свойствам и методам объекта через имя объекта
MyClass.MyObject.objectMethod()


Companion Object (компаньон-объект)
Companion object позволяет определить статические члены класса. Эти члены доступны без создания экземпляра класса. Вы можете использовать companion object для хранения статических методов и свойств, которые могут быть вызваны напрямую через имя класса.
class MyClass {
let instanceProperty = "Instance Property"

companion object {
let companionProperty = "Companion Property"

func companionMethod() {
print("This is a companion object method")
}
}
}

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


🚩Основные различия

🟠Доступность
Обычный объект: Доступ к свойствам и методам обычного объекта осуществляется через его имя. Companion Object: Доступ к свойствам и методам компаньон-объекта осуществляется через имя класса.

🟠Использование в контексте экземпляров класса
Обычный объект: Не привязан к конкретному экземпляру класса и создается один раз для всего класса. Companion Object: Также не привязан к конкретному экземпляру класса и создается один раз для всего класса, но служит для определения статических членов класса.

🟠Неявное имя
Обычный объект: Требует явного имени для доступа. Companion Object: Имеет неявное имя Companion, если не указано другое имя. Это позволяет получить доступ к его членам без явного указания имени.

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

class MyClass {
val instanceProperty = "Instance Property"

object MyObject {
val objectProperty = "Object Property"

fun objectMethod() {
println("This is an object method")
}
}

companion object {
val companionProperty = "Companion Property"

fun companionMethod() {
println("This is a companion object method")
}
}
}

// Доступ к свойствам и методам объекта через имя объекта
println(MyClass.MyObject.objectProperty)
MyClass.MyObject.objectMethod()

// Доступ к свойствам и методам компаньон-объекта через имя класса
println(MyClass.companionProperty)
MyClass.companionMethod()


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

ARC (Automatic Reference Counting) — это система управления памятью, используемая в Swift и Objective-C, которая автоматически управляет жизненным циклом объектов. ARC отслеживает, сколько ссылок (или "счетчиков ссылок") указывает на объект, и освобождает его из памяти, когда счетчик достигает нуля. Это помогает предотвратить утечки памяти, хотя циклические ссылки всё равно могут требовать ручного разрыва.

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

Модуль в iOS-разработке представляет собой логически изолированную часть приложения, включающую все необходимые компоненты для выполнения определённой функции. Вот пример модуля User с использованием архитектурного шаблона VIPER:

🚩Пример структуры модуля `User`

- Modules
- User
- View
- UserView.swift
- UserViewController.swift
- Interactor
- UserInteractor.swift
- Presenter
- UserPresenter.swift
- Entity
- UserEntity.swift
- Router
- UserRouter.swift


🚩Пример кода для модуля `User`

UserView.swift
import UIKit

protocol UserViewProtocol: AnyObject {
var presenter: UserPresenterProtocol? { get set }
func showUserData(_ user: UserEntity)
}

class UserView: UIViewController, UserViewProtocol {
var presenter: UserPresenterProtocol?

override func viewDidLoad() {
super.viewDidLoad()
presenter?.viewDidLoad()
}

func showUserData(_ user: UserEntity) {
// Обновление UI с данными пользователя
}
}


UserInteractor.swift
protocol UserInteractorProtocol: AnyObject {
var presenter: UserPresenterProtocol? { get set }
func fetchUserData()
}

class UserInteractor: UserInteractorProtocol {
weak var presenter: UserPresenterProtocol?

func fetchUserData() {
let user = UserEntity(name: "John Doe", age: 30)
presenter?.didFetchUserData(user)
}
}


UserPresenter.swift
protocol UserPresenterProtocol: AnyObject {
var view: UserViewProtocol? { get set }
var interactor: UserInteractorProtocol? { get set }
var router: UserRouterProtocol? { get set }
func viewDidLoad()
func didFetchUserData(_ user: UserEntity)
}

class UserPresenter: UserPresenterProtocol {
weak var view: UserViewProtocol?
var interactor: UserInteractorProtocol?
var router: UserRouterProtocol?

func viewDidLoad() {
interactor?.fetchUserData()
}

func didFetchUserData(_ user: UserEntity) {
view?.showUserData(user)
}
}


UserEntity.swift
struct UserEntity {
let name: String
let age: Int
}


UserRouter.swift
protocol UserRouterProtocol: AnyObject {
static func createModule() -> UIViewController
}

class UserRouter: UserRouterProtocol {
static func createModule() -> UIViewController {
let view = UserView()
let presenter: UserPresenterProtocol & UserInteractorOutputProtocol = UserPresenter()
let interactor: UserInteractorProtocol = UserInteractor()
let router: UserRouterProtocol = UserRouter()

view.presenter = presenter
presenter.view = view
presenter.interactor = interactor
presenter.router = router
interactor.presenter = presenter

return view
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Расскажи об MVVM

MVVM (Model-View-ViewModel) — это архитектурный паттерн, часто используемый в разработке UI-приложений, где Model управляет данными, View отвечает за представление, а ViewModel связывает данные с представлением. ViewModel содержит логику и данные, необходимые для отображения в View, и часто использует привязку данных, чтобы автоматически обновлять интерфейс при изменении данных. Этот паттерн помогает разделить логику приложения и интерфейс, облегчая поддержку и тестирование кода.

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

В iOS-проектах обычно хранятся и управляются с помощью CocoaPods, популярного менеджера зависимостей для проектов на Swift и Objective-C. Вот основные моменты и шаги, связанные с хранением и управлением Pod'ами:

🚩Шаги

1⃣Установка CocoaPods
Установите CocoaPods, если он ещё не установлен, используя команду
sudo gem install cocoapods     


2⃣Создание Podfile
Перейдите в корневую директорию вашего проекта и создайте Podfile, если он ещё не создан, используя команду
pod init     


3⃣Конфигурация Podfile
Откройте Podfile и добавьте необходимые зависимости. Например:
platform :ios, '13.0'

target 'YourApp' do
use_frameworks!

# Подключение библиотек
pod 'Alamofire', '~> 5.4'
pod 'SwiftyJSON', '~> 5.0'
end


4⃣Установка Pod'ов
Установите Pod'ы, используя команду
pod install     


5⃣Открытие .xcworkspace
После установки Pod'ов откройте сгенерированный файл .xcworkspace вместо .xcodeproj для работы с проектом
open YourApp.xcworkspace     


🚩Хранение Pod'ов

Pod'ы, указанные в Podfile, загружаются и устанавливаются в директорию Pods, которая создаётся в корневой директории вашего проекта. Также CocoaPods создаёт или обновляет несколько файлов, таких как Podfile.lock, Pods/Manifest.lock и YourApp.xcworkspace.

🟠`Pods/`
Директория, где хранятся все установленные зависимости и их файлы.
🟠`Podfile.lock`
Файл, фиксирующий версии всех установленных Pod'ов, чтобы обеспечить согласованность между разработчиками.
🟠`Pods/Manifest.lock`
Файл, используемый CocoaPods для синхронизации состояния Pod'ов.
🟠`YourApp.xcworkspace`
Рабочая область, которая объединяет ваш проект и его зависимости.

🚩Практики управления

1⃣Добавление `Podfile` и `Podfile.lock` в систему контроля версий
Добавьте Podfile и Podfile.lock в ваш репозиторий (например, Git), чтобы обеспечить согласованность зависимостей между разработчиками.
git add Podfile Podfile.lock
git commit -m "Add Podfile and Podfile.lock"


2⃣Игнорирование директории `Pods/`
Обычно директорию Pods/ игнорируют в системе контроля версий, добавляя её в .gitignore.
Pods/     


3⃣Согласованность зависимостей
При клонировании репозитория или при изменении зависимостей выполните pod install, чтобы установить те же версии Pod'ов, что указаны в Podfile.lock.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
🤔 Какие есть паттерны в объектном проектировании

Среди паттернов объектного проектирования выделяются: порождающие паттерны (например, Singleton, Factory, Builder), структурные паттерны (Adapter, Composite, Decorator) и поведенческие паттерны (Observer, Strategy, Command). Порождающие паттерны помогают создавать объекты, структурные организуют отношения между объектами, а поведенческие управляют взаимодействиями и обязанностями объектов. Эти паттерны способствуют созданию гибкого и поддерживаемого кода.

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

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

🟠Композиция
Композиция предполагает включение объектов других классов в качестве полей и делегирование им работы. Это позволяет комбинировать различные компоненты и изменять их поведение во время выполнения.
protocol Engine {
func start()
}

class Car {
private let engine: Engine

init(engine: Engine) {
self.engine = engine
}

func start() {
engine.start()
}
}

class ElectricEngine: Engine {
func start() {
print("Electric engine starting...")
}
}

class GasolineEngine: Engine {
func start() {
print("Gasoline engine starting...")
}
}

let electricCar = Car(engine: ElectricEngine())
let gasolineCar = Car(engine: GasolineEngine())
electricCar.start() // Electric engine starting...
gasolineCar.start() // Gasoline engine starting...


🟠Протоколы и интерфейсы
Протоколы определяют набор методов и свойств, которые класс или структура должны реализовать. Это позволяет создавать гибкие и переиспользуемые компоненты.
protocol Drawable {
func draw()
}

class Circle: Drawable {
func draw() {
print("Drawing a circle")
}
}

class Square: Drawable {
func draw() {
print("Drawing a square")
}
}

func render(drawable: Drawable) {
drawable.draw()
}

let shapes: [Drawable] = [Circle(), Square()]
shapes.forEach { render(drawable: $0) }


🟠Категории и расширения (Extensions)
Расширения позволяют добавлять новые методы и свойства к существующим классам, структурам или перечислениям без необходимости наследования или изменения исходного кода.
extension String {
func reverse() -> String {
return String(self.reversed())
}
}

let original = "hello"
let reversed = original.reverse()
print(reversed) // "olleh"


🟠Делегирование
Делегирование предполагает передачу ответственности за выполнение определенных задач другому объекту. Это часто используется для создания гибких и переиспользуемых компонентов.
protocol PrinterDelegate: AnyObject {
func printerDidFinishPrinting(_ printer: Printer)
}

class Printer {
weak var delegate: PrinterDelegate?

func printDocument() {
// Печать документа
print("Printing document...")
// Уведомление делегата о завершении печати
delegate?.printerDidFinishPrinting(self)
}
}

class PrintManager: PrinterDelegate {
func printerDidFinishPrinting(_ printer: Printer) {
print("Document printing completed.")
}
}

let printer = Printer()
let manager = PrintManager()

printer.delegate = manager
printer.printDocument()
// "Printing document..."
// "Document printing completed."


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