Anonymous Quiz
3%
enumerator
1%
Enumerable
96%
enum
0%
EnumType
UIKit
UIView.animate(withDuration: 0.5) {
myView.alpha = 0.5
myView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
}
UIView.animateKeyframes(withDuration: 2.0, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5) {
myView.transform = CGAffineTransform(rotationAngle: .pi / 4)
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
myView.transform = CGAffineTransform(rotationAngle: -.pi / 4)
}
}, completion: nil)
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = CGPoint(x: 0, y: 0)
animation.toValue = CGPoint(x: 100, y: 100)
animation.duration = 1.0
myView.layer.add(animation, forKey: "positionAnimation")
UIView.transition(with: myView, duration: 0.5, options: .transitionFlipFromLeft, animations: {
myView.isHidden = !myView.isHidden
}, completion: nil)
SwiftUI
struct ContentView: View {
@State private var scale: CGFloat = 1.0
var body: some View {
VStack {
Button("Animate") {
withAnimation {
scale += 0.5
}
}
.padding()
Rectangle()
.frame(width: 100, height: 100)
.scaleEffect(scale)
}
}
}
struct ContentView: View {
@State private var showRectangle = false
var body: some View {
VStack {
Button("Toggle") {
withAnimation {
showRectangle.toggle()
}
}
.padding()
if showRectangle {
Rectangle()
.frame(width: 100, height: 100)
.transition(.slide)
}
}
}
}
struct ContentView: View {
@State private var rotation: Double = 0
var body: some View {
VStack {
Button("Rotate") {
withAnimation(.easeInOut(duration: 1.0)) {
rotation += 45
}
}
.padding()
Rectangle()
.frame(width: 100, height: 100)
.rotationEffect(.degrees(rotation))
}
}
}
iOS предлагает широкий спектр анимаций в UIKit и SwiftUI, от базовых изменений свойств до сложных эффектов. Анимации делают интерфейс более динамичным и улучшают пользовательский опыт.
В двух фразах: iOS предоставляет множество анимаций в UIKit и SwiftUI для создания динамичных интерфейсов. Они варьируются от простых изменений свойств до сложных эффектов, улучшая пользовательский опыт.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Anonymous Quiz
18%
sort()
9%
map()
71%
filter()
3%
reduce()
В Swift и iOS, очереди (queues) используются для управления задачами и их выполнением в многопоточных приложениях. Основные виды очередей:
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
// Задача 1
}
serialQueue.async {
// Задача 2
}
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
concurrentQueue.async {
// Задача 1
}
concurrentQueue.async {
// Задача 2
}
DispatchQueue.main.async {
// Обновление UI
}
DispatchQueue.global(qos: .userInitiated).async {
// Задача с высоким приоритетом
}
DispatchQueue.global(qos: .background).async {
// Задача с низким приоритетом
}
let operationQueue = OperationQueue()
let operation1 = BlockOperation {
// Задача 1
}
let operation2 = BlockOperation {
// Задача 2
}
operation2.addDependency(operation1)
operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)
В iOS и Swift доступны различные виды очередей, такие как последовательные, конкурирующие, главная очередь, глобальные очереди и очереди операций. Они позволяют эффективно управлять многозадачностью и обеспечивать правильное выполнение задач в приложениях.
В двух фразах: В iOS есть последовательные и конкурирующие очереди, главная очередь для обновления UI, глобальные очереди для задач с разным приоритетом и очереди операций для сложных зависимостей. Они помогают управлять многозадачностью и обеспечивать корректное выполнение задач.
Please open Telegram to view this post
VIEW IN TELEGRAM
Anonymous Quiz
76%
Откладывает выполнение кода до выхода из текущего блока
10%
Задерживает вызов функции
4%
Определяет последовательность выполнения потоков
11%
Гарантирует выполнение кода после условного оператора
Основные способы передачи данных в iOS
class DetailViewController: UIViewController {
var data: String
init(data: String) {
self.data = data
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail",
let detailVC = segue.destination as? DetailViewController {
detailVC.data = "Hello, World!"
}
}
protocol DataDelegate: AnyObject {
func didReceiveData(_ data: String)
}
class Sender {
weak var delegate: DataDelegate?
func sendData() {
delegate?.didReceiveData("Hello, World!")
}
}
class Receiver: DataDelegate {
func didReceiveData(_ data: String) {
print(data)
}
}
let sender = Sender()
let receiver = Receiver()
sender.delegate = receiver
sender.sendData() // Output: Hello, World!
func fetchData(completion: @escaping (String) -> Void) {
let data = "Hello, World!"
completion(data)
}
fetchData { data in
print(data) // Output: Hello, World!
}
NotificationCenter.default.post(name: .didReceiveData, object: nil, userInfo: ["data": "Hello, World!"])
NotificationCenter.default.addObserver(forName: .didReceiveData, object: nil, queue: .main) { notification in
if let data = notification.userInfo?["data"] as? String {
print(data) // Output: Hello, World!
}
}
UserDefaults.standard.set("Hello, World!", forKey: "data")
if let data = UserDefaults.standard.string(forKey: "data") {
print(data) // Output: Hello, World!
}
let keychain = Keychain(service: "com.example.myapp")
keychain["data"] = "Hello, World!"
if let data = keychain["data"] {
print(data) // Output: Hello, World!
}
class DataManager {
static let shared = DataManager()
var data: String?
}
DataManager.shared.data = "Hello, World!"
print(DataManager.shared.data ?? "") // Output: Hello, World!
В iOS можно передавать данные через инициализаторы, сегвей, делегаты, замыкания, нотификации, UserDefaults, Keychain и общие ресурсы. Выбор метода зависит от конкретных требований.
В двух фразах: Данные в iOS можно передавать разными способами, включая инициализаторы, сегвей, делегаты, замыкания, нотификации, UserDefaults, Keychain и общие ресурсы. Каждый метод имеет свои применения и подходит для разных сценариев.
Please open Telegram to view this post
VIEW IN TELEGRAM
Anonymous Quiz
75%
Enumerations
2%
Classes
8%
Structures
15%
Tuples
Если убрать опционалы из Swift, это приведет к значительным изменениям в языке и его поведении, что окажет влияние на несколько ключевых аспектов программирования:
nil). Это помогает избежать неожиданных ошибок и делает код более безопасным. var name: String? = nil
if let unwrappedName = name {
print("Name is \(unwrappedName)")
} else {
print("Name is nil")
}
var name: String = "" // Значение по умолчанию
if name.isEmpty {
print("Name is nil")
} else {
print("Name is \(name)")
}
nil.?, !, if let и guard let.nil в случае неудачи. func findUser(byID id: Int) -> User? {
// Возвращает nil, если пользователь не найден
}
func findUser(byID id: Int) -> User {
// Возвращает пустого пользователя или значение по умолчанию
return User()
}
nil.nil.Удаление опционалов из Swift приведет к необходимости использования значений по умолчанию, ручной обработки отсутствующих значений и ошибок, что увеличит вероятность ошибок и сделает код менее безопасным и устойчивым. Опционалы помогают явно указывать на возможность отсутствия значения и обеспечивают более безопасное и надежное программирование.
В двух фразах: Удаление опционалов сделает код менее безопасным и устойчивым, увеличивая вероятность ошибок из-за отсутствующих значений. Опционалы важны для явного указания на возможность
nil и для повышения надежности кода.Please open Telegram to view this post
VIEW IN TELEGRAM
Anonymous Quiz
9%
`!`
54%
`?`
33%
`??`
5%
`->`
Мьютекс (от англ. "mutex" - mutual exclusion, взаимное исключение) — это механизм синхронизации, используемый в многопоточном программировании для предотвращения одновременного доступа нескольких потоков к общим ресурсам, таким как переменные, структуры данных или файлы. Он помогает избежать состояния гонки (race condition), когда результат выполнения программы зависит от неопределённого порядка доступа потоков к ресурсу.
В Swift можно использовать класс
NSLock для создания мьютексов:import Foundation
class SafeCounter {
private var value = 0
private let lock = NSLock()
func increment() {
lock.lock() // Захват мьютекса
value += 1
lock.unlock() // Освобождение мьютекса
}
func getValue() -> Int {
lock.lock() // Захват мьютекса
let currentValue = value
lock.unlock() // Освобождение мьютекса
return currentValue
}
}
let counter = SafeCounter()
DispatchQueue.global().async {
for _ in 0..<1000 {
counter.increment()
}
}
DispatchQueue.global().async {
for _ in 0..<1000 {
counter.increment()
}
}
// Подождём немного, чтобы дать потокам закончить работу
Thread.sleep(forTimeInterval: 1)
print("Final counter value: \(counter.getValue())")
Недостатки использования мьютексов
Мьютекс — это важный механизм для синхронизации доступа к общим ресурсам в многопоточном программировании. Он предотвращает одновременный доступ к ресурсам, обеспечивая их целостность и стабильность программы, но требует осторожного использования для избежания мёртвых блокировок и снижения производительности.
В двух фразах: Мьютекс позволяет предотвратить одновременный доступ нескольких потоков к общим ресурсам, обеспечивая безопасность данных. Это делает код более предсказуемым, но требует аккуратного использования для предотвращения мёртвых блокировок и снижения производительности.
Please open Telegram to view this post
VIEW IN TELEGRAM
Anonymous Quiz
7%
var
2%
const
84%
let
8%
fix
Оптимизация выполнения кода в Swift может быть достигнута различными методами, начиная с улучшения структуры кода и заканчивая использованием эффективных алгоритмов и данных. Вот несколько ключевых методов для оптимизации:
Set, для пар ключ-значение — Dictionary. var array = [1, 2, 3, 4, 5]
var set: Set = [1, 2, 3, 4, 5]
var dictionary = ["one": 1, "two": 2, "three": 3]
var name: String? = "John"
if let unwrappedName = name {
print("Name is \(unwrappedName)")
}
inout параметры для избежания копирования при передаче значений в функции. func increment(value: inout Int) {
value += 1
}
var number = 1
increment(value: &number)
OperationQueue для выполнения задач в фоновом режиме. DispatchQueue.global(qos: .background).async {
// Фоновая задача
DispatchQueue.main.async {
// Обновление UI на главном потоке
}
}
class MyClass {
lazy var expensiveObject: ExpensiveObject = {
return ExpensiveObject()
}()
}
var cache = [Int: Int]()
func fibonacci(_ n: Int) -> Int {
if let result = cache[n] {
return result
}
if n <= 1 { return n }
let result = fibonacci(n - 1) + fibonacci(n - 2)
cache[n] = result
return result
}
for i in 0..<1000 {
// Оптимизированный код
}
struct Point {
var x: Int
var y: Int
}
Оптимизация выполнения кода в Swift включает в себя выбор правильных структур данных, минимизацию использования опционалов, избежание ненужного копирования, использование асинхронности и параллелизма, ленивую загрузку, кэширование результатов, оптимизацию циклов и использование value types. Профилирование и анализ узких мест также играют ключевую роль в оптимизации.
В двух фразах: Оптимизировать выполнение кода в Swift можно с помощью правильного выбора структур данных, асинхронного выполнения задач, ленивой загрузки и кэширования результатов. Профилирование помогает выявить и устранить узкие места в производительности.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Anonymous Quiz
9%
Асинхронное выполнение кода
4%
Создание новой очереди
86%
Синхронное выполнение кода
1%
Управление памятью
В Swift автоматически генерируемый memberwise инициализатор доступен только для структур (structs), но не для классов (classes). Это связано с рядом различий между этими двумя типами и некоторыми особенностями их поведения.
class BaseClass {
var baseProperty: String
init(baseProperty: String) {
self.baseProperty = baseProperty
}
}
class SubClass: BaseClass {
var subProperty: Int
init(baseProperty: String, subProperty: Int) {
self.subProperty = subProperty
super.init(baseProperty: baseProperty)
}
}
class ResourceHandler {
var resource: Resource
init(resource: Resource) {
self.resource = resource
// Дополнительные действия по настройке ресурса
}
deinit {
// Освобождение ресурса
}
}
class Node {
var value: Int
var next: Node?
init(value: Int, next: Node?) {
self.value = value
self.next = next
}
}
class User {
var name: String
var age: Int
init(name: String, age: Int) {
guard age > 0 else {
fatalError("Возраст должен быть положительным")
}
self.name = name
self.age = age
}
}
Автоматическая генерация memberwise инициализатора для классов в Swift отсутствует из-за сложности, связанной с наследованием, управлением памятью, пользовательскими требованиями к инициализации и необходимостью учитывать сложные правила инициализации и деинициализации. Эти особенности требуют явного определения инициализаторов разработчиком для обеспечения правильной и безопасной работы классов.
В двух фразах: Swift не генерирует memberwise инициализаторы для классов из-за сложности, связанной с наследованием и управлением памятью, а также необходимости учитывать специфические требования к инициализации. Разработчики должны явно определять инициализаторы для обеспечения корректной работы классов.
Please open Telegram to view this post
VIEW IN TELEGRAM
Anonymous Quiz
36%
private
15%
fileprivate
46%
internal
3%
public
RunLoop — это фундаментальный механизм в iOS и macOS, который управляет циклом обработки событий в приложении. Он отслеживает и обрабатывает входящие события, такие как нажатия клавиш, касания экрана, таймеры и сетевые запросы, и поддерживает приложение в активном состоянии, пока оно не завершится.RunLoop постоянно выполняет цикл, ожидая входящие события и обрабатывая их по мере поступления. Этот цикл состоит из нескольких этапов: ожидание события, обработка события и повтор цикла.RunLoop может работать в разных режимах, которые определяют, какие источники событий будут отслеживаться и обрабатываться. Основные режимы включают default и tracking (для событий отслеживания, таких как прокрутка). В каждой итерации RunLoop обрабатывает события только для текущего режима.RunLoop.current.run(mode: .default, before: Date.distantFuture)
RunLoop может отслеживать различные источники событий, такие как таймеры (Timer), порты (Port), ввод пользователей (такие как касания экрана и клики мыши), а также пользовательские источники (Input Source).RunLoop может управлять таймерами, которые выполняют задачи через определенные интервалы времени. let timer = Timer(timeInterval: 1.0, repeats: true) { _ in
print("Timer fired!")
}
RunLoop.current.add(timer, forMode: .default)
RunLoop используется для обработки событий в основном потоке (main thread) приложения. Это особенно важно для поддержания отзывчивости пользовательского интерфейса, поскольку все взаимодействия с UI происходят в основном потоке.import Foundation
class Example {
var timer: Timer?
func startRunLoop() {
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
RunLoop.current.run()
}
@objc func timerFired() {
print("Timer fired!")
}
}
let example = Example()
example.startRunLoop()
RunLoop — это ключевой компонент в iOS и macOS, обеспечивающий цикл обработки событий в приложении. Он управляет различными источниками событий и таймерами, обеспечивая поддержку активного состояния приложения и отзывчивость пользовательского интерфейса.В двух фразах:
RunLoop управляет циклом обработки событий в приложении, отслеживая и обрабатывая входящие события. Это позволяет поддерживать активное состояние приложения и обеспечивает отзывчивость пользовательского интерфейса.Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Anonymous Quiz
1%
Увеличивает производительность
2%
Отключает ARC
94%
Делает замыкание сохраняемым после выхода функции
3%
Обеспечивает доступ к приватным данным
RSI может обозначать разные вещи в зависимости от контекста, но наиболее часто эта аббревиатура используется в следующих двух областях:Relative Strength Index (RSI) — это технический индикатор, используемый в анализе финансовых рынков для оценки силы и скорости изменения цен актива. RSI помогает определить перекупленность или перепроданность актива, что может указывать на возможность коррекции цены или разворота тренда.
\[
RSI = 100 - \left(\frac{100}{1 + RS}\right)
\]
где RS (Relative Strength) = среднее значение закрытия вверх / среднее значение закрытия вниз.
import Foundation
// Пример функции для расчета RSI на Swift
func calculateRSI(prices: [Double]) -> Double? {
guard prices.count >= 14 else { return nil }
let averageGain = prices[1..<14].filter { $0 >= 0 }.reduce(0, +) / 14
let averageLoss = prices[1..<14].filter { $0 < 0 }.reduce(0, +).magnitude / 14
guard averageLoss != 0 else { return 100 }
let rs = averageGain / averageLoss
let rsi = 100 - (100 / (1 + rs))
return rsi
}
let prices = [1.1, 1.2, 1.15, 1.2, 1.25, 1.3, 1.35, 1.4, 1.45, 1.5, 1.55, 1.6, 1.65, 1.7]
if let rsi = calculateRSI(prices: prices) {
print("RSI: \(rsi)")
}
Repetitive Strain Injury (RSI) — это медицинский термин, обозначающий травмы, возникающие в результате повторяющихся движений или чрезмерного использования определенных частей тела, обычно рук и кистей. RSI часто встречается у людей, работающих за компьютером, музыкантов, спортсменов и тех, кто выполняет повторяющиеся физические задачи.
RSI может означать как технический индикатор Relative Strength Index в финансах, так и медицинское состояние Repetitive Strain Injury. В финансах RSI помогает анализировать состояние рынка, в то время как в медицине RSI относится к травмам, вызванным повторяющимися движениями.
В двух фразах: В финансах RSI — это индикатор силы цены актива, показывающий перекупленность или перепроданность. В медицине RSI — это травмы от повторяющихся движений, требующие профилактики и лечения.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯8👀3
Anonymous Quiz
62%
?
4%
!
32%
??
1%
@
😁20🤯1
Словарь (dictionary) в программировании — это структура данных, которая хранит пары ключ-значение. В Swift словарь представлен типом
Dictionary<K, V>, где K — это тип ключей, а V — тип значений. Словари широко используются из-за их эффективности и удобства. Вот основные причины и примеры использования словарей:var phoneBook: [String: String] = ["Alice": "123-4567", "Bob": "987-6543"]
if let number = phoneBook["Alice"] {
print("Alice's phone number is \(number)")
}
var inventory: [String: Int] = ["Apples": 10, "Bananas": 5]
inventory["Apples"] = 15 // Обновление количества яблок
struct Person {
let name: String
let age: Int
}
var people: [String: Person] = ["Alice": Person(name: "Alice", age: 30), "Bob": Person(name: "Bob", age: 25)]
if let person = people["Alice"] {
print("\(person.name) is \(person.age) years old")
}
var studentGrades: [String: [String: Double]] = [
"Alice": ["Math": 95, "Science": 90],
"Bob": ["Math": 85, "Science": 80]
]
if let aliceGrades = studentGrades["Alice"] {
print("Alice's Math grade is \(aliceGrades["Math"] ?? 0)")
}
Словари часто используются в алгоритмах для эффективного хранения и поиска данных, а также в реализации более сложных структур данных, таких как графы и хеш-таблицы.
Хранение данных о студентах
var students: [Int: String] = [101: "Alice", 102: "Bob", 103: "Charlie"]
if let student = students[102] {
print("Student with ID 102 is \(student)")
}
Подсчет частоты элементов
let words = ["apple", "banana", "apple", "orange", "banana", "apple"]
var wordCount: [String: Int] = [:]
for word in words {
wordCount[word, default: 0] += 1
}
print(wordCount) // ["apple": 3, "banana": 2, "orange": 1]
var settings: [String: Any] = ["theme": "dark", "notificationsEnabled": true]
if let theme = settings["theme"] as? String {
print("Current theme is \(theme)")
}
Словари в Swift предоставляют эффективный и удобный способ хранения и управления данными, обеспечивая быстрый доступ, уникальные ключи, гибкость в типах данных и возможность группировки связанных данных. Они широко используются в различных приложениях для решения множества задач.
В двух фразах: Словари позволяют эффективно хранить и управлять данными, предоставляя быстрый доступ к значениям по уникальным ключам. Они гибки и удобны для различных приложений, от простого хранения до сложных алгоритмов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1