open — это публичный и наследуемый класс с возможностью переопределения методов за пределами модуля.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
В программировании стек (
stack) — это структура данных и область памяти, используемая для хранения временных данных. В зависимости от контекста, стек может существовать в нескольких местах.Это главная область памяти в оперативной памяти (RAM), где хранятся:
- Локальные переменные функций.
- Адреса возврата после завершения функции.
- Контекст выполнения программы.
func functionA() {
functionB()
}
func functionB() {
print("Вызов B")
}
functionA()func infiniteRecursion() {
infiniteRecursion() // ❌ Бесконечный вызов
}В Swift можно реализовать стек вручную, используя массив (
Array).struct Stack<T> {
private var elements: [T] = []
mutating func push(_ item: T) {
elements.append(item)
}
mutating func pop() -> T? {
return elements.popLast()
}
}
var stack = Stack<Int>()
stack.push(10)
stack.push(20)
print(stack.pop()!) // 20Каждый поток (
Thread) в многопоточном программировании получает свой стек.DispatchQueue.global().async {
print("Фоновый поток")
}
print("Главный поток")Swift использует Automatic Reference Counting (ARC) для управления памятью.
Когда объект больше не нужен, он удаляется из памяти (в том числе из стека).
func createPerson() {
let person = "Иван" // Создаётся в стеке
print(person)
}
createPerson() // Переменная person удаляется при выходе из функцииСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1🤔1💊1
Forwarded from Идущий к IT
🔥 Записал видос "Как за 3 минуты настроить Автоотклики на вакансии HeadHunter" больше не придется заниматься этой унылой рутиной
📺 Видео: https://youtu.be/G_FOwEGPwlw
Please open Telegram to view this post
VIEW IN TELEGRAM
Эта информация обычно сохраняется в UserDefaults (iOS), SharedPreferences (Android) или в базе/сервере, если нужна синхронизация. Система может также использовать системную тему, и приложения её подхватывают автоматически.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Когда вы открываете несколько экранов (UIViewController) в iOS, они обычно создают стек представлений (View Controller Stack). В зависимости от способа открытия экранов (модально или через навигационный стек), поведение
dismiss будет разным.Если экраны открывались модально (
present), то dismiss на последнем экране просто закроет только этот экран, и управление вернётся к предыдущему. let newVC = UIViewController()
present(newVC, animated: true)
Позже вызываем:
dismiss(animated: true)
Если вызвать
dismiss на первом модально представленном контроллере, все последующие модальные контроллеры закроются сразу.// Открываем два экрана последовательно
let vc1 = UIViewController()
let vc2 = UIViewController()
present(vc1, animated: true)
vc1.present(vc2, animated: true)
Если вызвать
dismiss на vc2:vc2.dismiss(animated: true)
Если вызвать
dismiss на vc1:vc1.dismiss(animated: true)
Если экраны открывались через
UINavigationController (pushViewController), то dismiss не работает для удаления последнего экрана. Нужно использовать popViewController.let vc1 = UIViewController()
let vc2 = UIViewController()
navigationController?.pushViewController(vc1, animated: true)
navigationController?.pushViewController(vc2, animated: true)
Теперь если мы вызовем:
vc2.dismiss(animated: true)
Правильный способ закрытия последнего экрана в
UINavigationController:navigationController?.popViewController(animated: true)
Если вы хотите закрыть весь стек экранов, используйте:
navigationController?.popToRootViewController(animated: true)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2💊1
Когда пользователь нажимает на иконку приложения на домашнем экране, iOS проходит несколько этапов перед тем, как приложение становится активным.
iOS-устройства управляются системой SpringBoard – это оболочка, отвечающая за домашний экран, иконки, фоновые процессы.
Когда пользователь тапает на иконку приложения, SpringBoard отправляет событие
UIApplicationLaunchOptionsKey в систему. Если приложение не запущено:
- iOS создаёт новый процесс и выделяет память.
- Загружаются зависимости (библиотеки, фреймворки).
- Создаётся объект
UIApplication. Здесь приложение инициализируется и загружается основной UI.
Метод в
AppDelegate: func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print("Приложение запущено")
return true
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
dispatch_async — выполняет задачу асинхронно, не дожидаясь завершения, и позволяет продолжить выполнение кода.
dispatch_sync — запускает задачу синхронно и блокирует текущий поток до её окончания. Используется, когда важно дождаться результата, но может привести к зависанию, если применён неаккуратно.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
В Swift переменные (свойства), объявленные в протоколе, должны указывать:
Если свойство объявлено как
{ get }, класс или структура, реализующая протокол, должна предоставить как минимум геттерprotocol Animal {
var name: String { get } // Только чтение
}
struct Dog: Animal {
let name = "Барсик" // Реализуем только get
}
let dog = Dog()
print(dog.name) // "Барсик"Можно также использовать вычисляемое свойство:
struct Cat: Animal {
var name: String {
return "Мурзик"
}
}Если свойство
{ get set }, класс или структура обязательно должны предоставить и get, и set.protocol Vehicle {
var speed: Int { get set } // Чтение и запись
}
class Car: Vehicle {
var speed: Int = 100 // Реализуем и get, и set
}
let car = Car()
car.speed = 120 // Можно изменить значение
print(car.speed) // 120Вычисляемое свойство тоже подойдёт, если оно имеет
get и set:class Bike: Vehicle {
private var internalSpeed = 50
var speed: Int {
get { return internalSpeed }
set { internalSpeed = newValue }
}
}Если свойство должно быть общим для всех экземпляров (не индивидуальным), то оно объявляется
static.protocol Config {
static var appVersion: String { get }
}
struct AppSettings: Config {
static let appVersion = "1.0.0"
}
print(AppSettings.appVersion) // "1.0.0"Класс может использовать
class var, если свойство можно переопределять в подклассах:class AppInfo: Config {
class var appVersion: String {
return "2.0.0"
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Да, отслеживание статуса задачи в
DispatchWorkItem может быть полезным, но это зависит от требований приложения. Если задача может быть отменена (
cancel()) Если выполнение задачи можно приостановить или продолжить
Если нужно проверить завершение перед выполнением следующего действия*
let workItem = DispatchWorkItem {
print("Задача выполняется")
}
// Запускаем задачу
DispatchQueue.global().async(execute: workItem)
// Отмена перед выполнением
workItem.cancel()
// Проверяем статус выполнения
if workItem.isCancelled {
print("Задача отменена")
} else {
print("Задача выполнена")
}В
DispatchWorkItem нет метода проверки завершения. Но можно вручную отслеживать завершение с помощью
notify: let workItem = DispatchWorkItem {
print("Задача выполняется")
}
// Сообщаем о завершении
workItem.notify(queue: .main) {
print("Задача завершена")
}
DispatchQueue.global().async(execute: workItem)Если задача короткая и простая → НЕ ОБЯЗАТЕЛЬНО.
Если задача важная, может быть отменена или зависит от других задач → ЛУЧШЕ ОТСЛЕЖИВАТЬ.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это классификация различных видов данных, которые могут быть использованы и манипулированы в программе. Они определяют, какие операции можно выполнять с данными и как они хранятся в памяти.
Представляют целые числа.
Int, UInlet age: Int = 25
Представляют дробные числа.
Float, Doublelet pi: Double = 3.14159
Представляют логические значения
true или false. Boollet isActive: Bool = true
Представляют отдельные символы.
Characterlet letter: Character = "A"
Представляют последовательности символов.
Stringlet greeting: String = "Hello, World!"
Представляют упорядоченные коллекции элементов одного типа.
Array<T>let numbers: [Int] = [1, 2, 3, 4, 5]
Представляют коллекции пар ключ-значение.
Dictionary<Key, Value>let user: [String: String] = ["name": "Alice", "age": "30"]
Представляют коллекции уникальных элементов.
Set<T>let uniqueNumbers: Set<Int> = [1, 2, 3, 4, 5]
Представляют тип данных с набором связанных значений.
enum enum CompassPoint {
case north
case south
case east
case west
}
Представляют группы связанных значений.
struct struct Person {
var name: String
var age: Int
}
let person = Person(name: "Alice", age: 30)
Представляют объекты с состоянием и поведением.
class class Car {
var model: String
var year: Int
init(model: String, year: Int) {
self.model = model
self.year = year
}
}
let car = Car(model: "Tesla", year: 2021)
Представляют группы нескольких значений различных типов.
(Type1, Type2, ...)let coordinates: (Int, Int) = (10, 20)
Представляют значение, которое может быть либо некоторым значением, либо nil.
Optional<T>var optionalName: String? = "Alice"
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
В Clean Swift (VIP) сущности делятся на Interactor, Presenter и ViewController. Сущность из MVC преобразуется в модель запроса/ответа (Request/Response), ViewModel и передаётся по цепочке: VC → Interactor → Presenter → View.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊4👍1
Утечка памяти (
memory leak) – это ситуация, когда память остаётся выделенной, но больше не используется программой и не освобождается. class Person {
var pet: Pet?
deinit { print("Person удалён") }
}
class Pet {
var owner: Person?
deinit { print("Pet удалён") }
}
var person: Person? = Person()
var pet: Pet? = Pet()
person?.pet = pet
pet?.owner = person
person = nil
pet = nilСлабые (
weak) или безвладельческие (unowned) ссылки не увеличивают счётчик ссылок, что разрывает цикл.class Person {
var pet: Pet?
deinit { print("Person удалён") }
}
class Pet {
weak var owner: Person? // Слабая ссылка
deinit { print("Pet удалён") }
}
var person: Person? = Person()
var pet: Pet? = Pet()
person?.pet = pet
pet?.owner = person
person = nil // "Person удалён"
pet = nil // "Pet удалён"unowned похож на weak, но он не может быть `nil`.class Owner {
var car: Car?
deinit { print("Owner удалён") }
}
class Car {
unowned var owner: Owner // Безвладельческая ссылка
init(owner: Owner) { self.owner = owner }
deinit { print("Car удалён") }
}
var owner: Owner? = Owner()
owner?.car = Car(owner: owner!)
owner = nil // "Owner удалён", "Car удалён"Замыкания захватывают объекты, создавая циклические ссылки.
Проблема:
self удерживается замыканиемclass ViewController {
var closure: (() -> Void)?
func setup() {
closure = {
print(self) // Удерживает self, создавая цикл!
}
}
deinit { print("ViewController удалён") }
}
var vc: ViewController? = ViewController()
vc?.setup()
vc = nil // ❌ "ViewController" НЕ удалится- Открываем
Xcode > Product > Profile. - Выбираем
Leaks. - Запускаем приложение и проверяем, остаются ли объекты в памяти.
Если метод
deinit не вызывается – значит, объект утёк в память.class Test {
deinit { print("Test удалён") }
}
var obj: Test? = Test()
obj = nil // Должно напечатать "Test удалён"- В Xcode открываем "Debug Memory Graph" (нажимая значок в Debugger).
- Смотрим, какие объекты остались в памяти.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Классы — это ссылочные типы в Swift, которые позволяют создавать объекты с общими свойствами и методами. Они поддерживают наследование, работают с ARC (Automatic Reference Counting) и хранятся в куче (heap).
Когда вы присваиваете класс другой переменной, копируется не сам объект, а ссылка на него. Изменения, сделанные через одну ссылку, затронут и другие.
В отличие от структур, которые хранятся в стеке, классы создают объекты в куче. Это позволяет передавать объекты между функциями без копирования.
Swift использует ARC для управления памятью. Объект удаляется из памяти, когда на него больше нет ссылок.
В отличие от структур, классы могут наследовать свойства и методы от других классов. Поддерживают переопределение методов (
override). Два объекта класса можно сравнивать по ссылке (
===), а не только по значению (==). class Animal {
var name: String
init(name: String) {
self.name = name
}
func speak() {
print("Some sound")
}
}
class Dog: Animal {
override func speak() {
print("Woof!")
}
}
let dog1 = Dog(name: "Buddy")
let dog2 = dog1 // Копируется ссылка, а не объект
dog2.name = "Charlie"
print(dog1.name) // "Charlie", так как dog1 и dog2 указывают на один объектСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Ключевые нюансы: захват значений (в т.ч. возможные retain cycles), необходимость указывать [weak self], использование замыканий в качестве обратных вызовов и обработчиков. Также важно понимать отличия между escaping и non-escaping closures — то есть тех, которые выходят за пределы области вызова.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Память устройства можно представить в виде нескольких уровней, каждый из которых имеет свою скорость доступа, размер и назначение:
Это самая быстрая память, непосредственно встроенная в процессор. Регистры хранят те данные, с которыми процессор работает в данный момент времени.
Она находится непосредственно на процессоре или рядом с ним. Кэш-память используется для временного хранения копий часто используемых данных из основной памяти для ускорения доступа к ним. Кэш-память делится на несколько уровней (L1, L2, и иногда L3), где L1 — самый быстрый и обычно самый маленький.
Здесь хранятся данные и программы, с которыми компьютер работает в данный момент. Доступ к ОЗУ быстрый, но оно является временным хранилищем: при выключении устройства данные в ОЗУ теряются.
Это память для долговременного хранения данных. Она сохраняет информацию даже при выключении питания. HDD (жесткие диски) использовались ранее и работают на принципе магнитного записывания данных, в то время как SSD (твердотельные накопители) работают на основе флеш-памяти и обеспечивают более быстрый доступ к данным.
Это техника, которая позволяет операционной системе использовать часть жесткого диска (или SSD) как дополнительную оперативную память. Когда ОЗУ заполнено, операционная система может перемещать редко используемые данные из ОЗУ на диск в специальный файл подкачки (swap file), освобождая ОЗУ для других задач.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Auto Layout управляет позиционированием и размером элементов UI независимо от размера экрана. Параметры позволяют задать зависимости между элементами, адаптивность интерфейса, привязку к краям, отступы, пропорции.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Фреймы (frames) в iOS-разработке используются для задания размеров и расположения элементов интерфейса (UIView) вручную.
Когда нужно анимировать движение элемента, проще всего работать с его
frame, так как он напрямую управляет origin (координаты) и size (размеры). UIView.animate(withDuration: 0.5) {
self.button.frame.origin.x += 100
}Если вы не используете Auto Layout или хотите задать положение элементов программно,
frame позволяет точно указать размеры и координаты. let button = UIButton(type: .system)
button.frame = CGRect(x: 50, y: 100, width: 200, height: 50)
button.setTitle("Нажми меня", for: .normal)
view.addSubview(button)
При динамической подгрузке ячеек в
UITableView или UICollectionView можно вручную вычислять frame для ускорения работы, вместо использования Auto Layout, который может замедлить скроллинг.При рисовании или настройке слоев
CALayer используется frame, чтобы точно определить размеры слоя. let borderLayer = CALayer()
borderLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
borderLayer.borderWidth = 2
borderLayer.borderColor = UIColor.red.cgColor
view.layer.addSublayer(borderLayer)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1