Структуры данных используются для эффективного хранения и управления данными в различных задачах.
Хранение элементов одного типа с доступом по индексу. Список товаров в корзине.
let shoppingCart = ["Apple", "Banana", "Orange"]
Хранение пар ключ-значение. Информация о пользователях по ID.
var userInfo = ["userID1": "John Doe"]
Хранение уникальных элементов. Уникальные теги постов.
var uniqueTags: Set = ["swift", "programming"]
Управление данными в стиле LIFO. Отмена последнего действия.
struct Stack<T> {
private var elements: [T] = []
mutating func push(_ element: T) { elements.append(element) }
mutating func pop() -> T? { elements.popLast() }
} Управление данными в стиле FIFO. Обработка запросов.
struct Queue<T> {
private var elements: [T] = []
mutating func enqueue(_ element: T) { elements.append(element) }
mutating func dequeue() -> T? { elements.isEmpty ? nil : elements.removeFirst() }
} Эффективное добавление и удаление элементов. Управление заказами.
class Node<T> { var value: T; var next: Node?; init(value: T) { self.value = value } } Иерархическая структура данных. Файловая система.
class TreeNode<T> { var value: T; var children: [TreeNode] = [] } Моделирование сетей и связей. Социальные сети.
class Graph { var adjList: [String: [String]] = [:] } Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
private (доступ только внутри текущего файла или типа),
fileprivate (доступ в пределах файла),
internal (доступ по умолчанию в модуле),
public (доступ в любом модуле),
open (доступ для наследования и изменения вне модуля).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Хранение уникальных элементов. Неупорядоченная коллекция. Быстрый поиск элементов.
var uniqueTags: Set = ["swift", "ios", "programming"]
Хранение пар ключ-значение. Неупорядоченная коллекция с ассоциативным доступом. Быстрый доступ к значениям по ключам.
var userInfo: [String: String] = ["userID1": "John Doe", "userID2": "Jane Smith"]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это архитектурные паттерны, используемые в разработке программного обеспечения для разделения логики и представления данных.
Компоненты
Model: Управляет данными и бизнес-логикой.
View: Отвечает за отображение данных и пользовательский интерфейс.
Presenter: Посредник между Model и View. Получает данные из Model и обновляет View.
Связь
View знает о Presenter и взаимодействует с ним.
Presenter знает о View и Model, взаимодействует с обоими.
protocol View: AnyObject {
func updateUI()
}
protocol Presenter {
func loadData()
}
class Model {
var data: String = "Hello, MVP"
}
class MyPresenter: Presenter {
private weak var view: View?
private var model: Model
init(view: View, model: Model) {
self.view = view
self.model = model
}
func loadData() {
// Получение данных из модели
view?.updateUI()
}
}
class MyViewController: UIViewController, View {
var presenter: Presenter!
override func viewDidLoad() {
super.viewDidLoad()
presenter.loadData()
}
func updateUI() {
// Обновление пользовательского интерфейса
}
}Компоненты
Model: Управляет данными и бизнес-логикой.
View: Отвечает за отображение данных и пользовательский интерфейс.
ViewModel: Абстракция, связывающая Model и View. Формирует данные для View и обрабатывает действия от View.
Связь
ViewModel знает о Model и может наблюдать за изменениями в ней. ViewModel предоставляет данные и команды для View. View знает только о ViewModel и не знает о Model напрямую.
class Model {
var data: String = "Hello, MVM"
}
class ViewModel {
private var model: Model
var displayData: String {
return model.data
}
init(model: Model) {
self.model = model
}
func updateModelData(newData: String) {
model.data = newData
}
}
class MyViewController: UIViewController {
var viewModel: ViewModel!
override func viewDidLoad() {
super.viewDidLoad()
// Обновление пользовательского интерфейса с использованием viewModel
print(viewModel.displayData)
}
}MVP: View взаимодействует с Presenter, а Presenter взаимодействует с View и Model.
MVM: View взаимодействует только с ViewModel, а ViewModel взаимодействует с Model.
MVP: View и Presenter имеют двустороннюю зависимость, что может усложнить управление зависимостями.
MVM: ViewModel не зависит от View, что улучшает тестируемость и упрощает архитектуру.
MVP: Тестирование Presenter может быть сложным из-за зависимости от View.
MVM: ViewModel легко тестируется независимо от View.
MVP: Чаще используется в Android-разработке.
MVM: Популярен в iOS-разработке и при использовании SwiftUI.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Выбор архитектурного паттерна для разработки приложения зависит от множества факторов, таких как специфика проекта, опыт команды и особенности используемой платформы.
MVP разделяет логику интерфейса пользователя и бизнес-логику, что делает код более модульным и управляемым.
Легче тестировать Presenter отдельно от View, что улучшает покрытие тестами и упрощает отладку.
Presenter управляет всей логикой взаимодействия с View, что делает структуру кода понятной и предсказуемой.
MVP хорошо подходит для проектов с сложной логикой UI, где требуется много взаимодействий между пользовательским интерфейсом и бизнес-логикой.
ViewModel не знает о View, что уменьшает связанность и улучшает тестируемость.
MVVM особенно хорошо работает с фреймворками, поддерживающими привязки данных, такими как SwiftUI или RxSwift. Это упрощает синхронизацию данных между View и ViewModel.
ViewModel формирует данные для View, что упрощает логику представления и делает код более чистым.
ViewModel легко тестируется, поскольку не зависит от конкретной реализации View, что улучшает модульное тестирование.
Использование MVVM в SwiftUI позволяет легко управлять состоянием приложения и автоматически обновлять интерфейс при изменении данных.
MVVM отлично сочетается с реактивным программированием, предоставляя мощные возможности для управления асинхронными операциями.
import SwiftUI
class Model {
var data: String = "Hello, MVVM"
}
class ViewModel: ObservableObject {
@Published var displayData: String = ""
private var model: Model
init(model: Model) {
self.model = model
self.displayData = model.data
}
func updateData(newData: String) {
model.data = newData
self.displayData = newData
}
}
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
Text(viewModel.displayData)
}
}
MVP используется для четкого разделения логики представления и бизнес-логики в сложных проектах на UIKit.
protocol View: AnyObject {
func updateUI(with data: String)
}
class Model {
var data: String = "Hello, MVP"
}
class Presenter {
private weak var view: View?
private var model: Model
init(view: View, model: Model) {
self.view = view
self.model = model
}
func loadData() {
view?.updateUI(with: model.data)
}
}
class ViewController: UIViewController, View {
private var presenter: Presenter!
override func viewDidLoad() {
super.viewDidLoad()
presenter = Presenter(view: self, model: Model())
presenter.loadData()
}
func updateUI(with data: String) {
// Обновление интерфейса
print(data)
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
В программировании существуют различные типы ссылок, которые определяют, как объекты управляются и удерживаются в памяти.
По умолчанию в Swift все ссылки являются сильными. Сильная ссылка удерживает объект в памяти до тех пор, пока существует хотя бы одна сильная ссылка на него. Для стандартного владения объектами.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person1: Person? = Person(name: "Alice")
var person2 = person1 // person2 также является сильной ссылкой на тот же объект Слабая ссылка не удерживает объект в памяти. Если все сильные ссылки на объект удаляются, объект освобождается, и слабая ссылка автоматически становится nil. Для предотвращения циклов удержания, особенно в делегатах и замыканиях.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
class Apartment {
weak var tenant: Person?
}
var alice: Person? = Person(name: "Alice")
var apt = Apartment()
apt.tenant = alice // Слабая ссылка на alice Неактивная ссылка, как и слабая, не удерживает объект в памяти, но в отличие от слабой ссылки, она не может быть nil. Используется, когда объект гарантированно существует на протяжении всего жизненного цикла. Для циклических зависимостей, где одна сторона всегда будет существовать.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
class Apartment {
unowned var tenant: Person
init(tenant: Person) {
self.tenant = tenant
}
}
var alice: Person? = Person(name: "Alice")
var apt = Apartment(tenant: alice!) // Неактивная ссылка на alice Предоставляют прямой доступ к объекту без автоматического управления памятью. Используется редко и требует ручного управления памятью. Для специфических задач, где необходим контроль над управлением памятью.
import Foundation
let unmanagedReference = Unmanaged.passRetained(NSObject())
let retainedObject = unmanagedReference.takeRetainedValue()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
В iOS-разработке существует несколько способов создания и управления макетами (layouts) пользовательского интерфейса.
Визуальный редактор, встроенный в Xcode, который позволяет разрабатывать пользовательский интерфейс с помощью перетаскивания элементов. Удобный графический интерфейс, быстрый просмотр изменений, поддержка Auto Layout. Меньшая гибкость по сравнению с программным кодом. Создание и настройка интерфейса с помощью storyboard или xib файлов.
Система ограничений (constraints), которая позволяет определять правила расположения и размеров элементов интерфейса. Адаптивные интерфейсы для различных устройств и ориентаций, мощные инструменты для сложных макетов. Может быть сложно освоить, особенно для сложных макетов.
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
Создание и настройка элементов интерфейса полностью через код, без использования Interface Builder. Полный контроль над процессом создания интерфейса, легко управлять версиями. Требует больше времени и усилий для настройки, особенно для сложных макетов.
let label = UILabel(frame: CGRect(x: 50, y: 50, width: 200, height: 50))
label.text = "Hello, World!"
view.addSubview(label)
Компоненты интерфейса, которые автоматически располагают и масштабируют свои подвиды (subviews) в вертикальном или горизонтальном направлении. Упрощает создание и управление сложными макетами, поддержка Auto Layout.: Ограниченная гибкость для некоторых типов макетов.
let stackView = UIStackView(arrangedSubviews: [label, button])
stackView.axis = .vertical
stackView.spacing = 10
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
Новый декларативный фреймворк для создания пользовательских интерфейсов, представленный Apple в 2019 году. Декларативный синтаксис, простой в использовании, интеграция с Swift, поддержка различных платформ (iOS, macOS, watchOS, tvOS). Требует iOS 13 и выше, меньшая поддержка старых устройств.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
Button(action: {
print("Button tapped")
}) {
Text("Tap me")
}
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Каждый способ создания макетов (layout'а) в iOS-разработке имеет свои преимущества и недостатки.
Удобный графический интерфейс для быстрой настройки и визуального просмотра изменений.
Простая настройка ограничений (constraints) для адаптивного интерфейса.
Возможность быстрого создания и изменения макетов без написания кода.
Ограниченные возможности для создания сложных и динамических макетов.
Трудности при слиянии изменений в storyboard или xib файлах в больших командах.
Более медленное время загрузки по сравнению с программными подходами.
Поддержка различных устройств и ориентаций экрана.
Возможность создания сложных и адаптивных макетов с помощью ограничений.
Упрощенная настройка ограничений через визуальный интерфейс.
Может быть сложно освоить, особенно для новичков.
Требует тщательного планирования и может стать сложным при работе с большим количеством ограничений.
Возможность точной настройки макета с помощью кода.
Легкость создания динамических и условных макетов.
Легче управлять изменениями в коде по сравнению с визуальными файлами.
Требует больше времени и усилий для настройки, особенно для сложных макетов.
Отсутствие визуального редактора может затруднить представление конечного результата.
Легкость создания и управления сложными макетами с минимальными усилиями.
Автоматическое управление ограничениями для вложенных элементов.
Поддержка различных ориентаций и размеров экранов.
Менее гибкие по сравнению с чистым Auto Layout или программными подходами.
Не всегда подходят для всех типов макетов, особенно для более сложных компоновок.
Простота и понятность кода благодаря декларативному подходу.
Мгновенное обновление интерфейса при изменении кода.
Современные возможности языка и тесная интеграция с экосистемой Apple.
Поддержка различных платформ (iOS, macOS, watchOS, tvOS).
Поддержка только iOS 13 и выше, что может ограничить использование на старых устройствах.
Некоторые функции еще находятся в стадии разработки, и могут быть ограничены возможности по сравнению с UIKit.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Являются важным механизмом управления памятью в Swift и других языках программирования с автоматическим управлением памятью.
Сильные ссылки гарантируют, что объект остается в памяти, пока на него существует хотя бы одна сильная ссылка. Без сильных ссылок объекты могли бы быть автоматически удалены сборщиком мусора, даже если они все еще нужны.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person1: Person? = Person(name: "Alice")
var person2 = person1 // person2 теперь также держит сильную ссылку на объектСильные ссылки контролируют время жизни объектов, предотвращая их преждевременное удаление из памяти. Объекты остаются живыми, пока они нужны, и удаляются только тогда, когда все сильные ссылки на них удаляются.
var person1: Person? = Person(name: "Alice")
person1 = nil // Объект "Alice" удаляется, если нет других сильных ссылок на него
Сильные ссылки часто используются для указания владения объектами. Владеющий объект держит сильную ссылку на подчиненный объект, обеспечивая его существование. ViewController держит сильные ссылки на UI-элементы, гарантируя, что они остаются в памяти, пока ViewController активен.
class ViewController {
var button: UIButton?
init() {
button = UIButton()
}
}
var viewController: ViewController? = ViewController()Сильные ссылки являются стандартным способом управления памятью и не требуют дополнительного кода для их создания и управления.
Они предотвращают утечки памяти, гарантируя, что объекты удаляются, когда на них больше нет ссылок.
Сильные ссылки делают код более предсказуемым, так как объекты остаются в памяти, пока они нужны.
Если два объекта имеют сильные ссылки друг на друга, они никогда не будут освобождены, что приведет к утечкам памяти. Это решается использованием слабых (weak) или неактивных (unowned) ссылок.
class Person {
var name: String
var friend: Person?
init(name: String) {
self.name = name
}
}
var alice: Person? = Person(name: "Alice")
var bob: Person? = Person(name: "Bob")
alice?.friend = bob
bob?.friend = alice
// Объекты alice и bob никогда не будут освобождены из памятиИспользование слабых (weak) или неактивных (unowned) ссылок для разрыва циклов сильных ссылок:
class Person {
var name: String
weak var friend: Person?
init(name: String) {
self.name = name
}
}
var alice: Person? = Person(name: "Alice")
var bob: Person? = Person(name: "Bob")
alice?.friend = bob
bob?.friend = alice
// Объекты alice и bob будут освобождены, когда на них не будет сильных ссылокСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
Слабые ссылки (weak references) играют важную роль в управлении памятью, особенно когда нужно предотвратить циклы сильных ссылок (retain cycles) и утечки памяти.
Циклы сильных ссылок возникают, когда два объекта держат сильные ссылки друг на друга, что препятствует их освобождению из памяти. Слабые ссылки разрывают этот цикл, позволяя одному из объектов освобождаться.
class Person {
var name: String
weak var friend: Person?
init(name: String) {
self.name = name
}
}
var alice: Person? = Person(name: "Alice")
var bob: Person? = Person(name: "Bob")
alice?.friend = bob
bob?.friend = alice
alice = nil // Теперь объекты могут быть освобождены
bob = nil Утечки памяти происходят, когда объекты, которые больше не нужны, не освобождаются из памяти. Слабые ссылки помогают избежать этих утечек, обеспечивая правильное освобождение памяти. Делегаты часто объявляются как слабые ссылки, чтобы избежать утечек памяти.
protocol TaskDelegate: AnyObject {
func taskDidFinish()
}
class Task {
weak var delegate: TaskDelegate?
func complete() {
delegate?.taskDidFinish()
}
}
class ViewController: TaskDelegate {
var task = Task()
init() {
task.delegate = self
}
func taskDidFinish() {
print("Task finished")
}
} Слабые ссылки удобны для временных зависимостей, когда объект не должен удерживаться в памяти, если нет других сильных ссылок. Использование слабых ссылок для временных объектов.
class Cache {
weak var temporaryObject: SomeClass?
}
class SomeClass {
// Код класса
}
var cache = Cache()
var object = SomeClass()
cache.temporaryObject = object
object = SomeClass() // Старый объект удаляется, так как на него нет сильных ссылок Основное преимущество слабых ссылок заключается в их способности разрывать циклы ссылок, предотвращая утечки памяти.
Слабые ссылки позволяют объектам освобождаться из памяти, когда на них больше нет сильных ссылок, что улучшает управление ресурсами.
Использование слабых ссылок обеспечивает более гибкое и безопасное управление зависимостями между объектами.
Необходимо учитывать, что слабые ссылки могут стать nil в любой момент, поэтому требуется дополнительная проверка.
Требуется хорошее понимание жизненного цикла объектов и управления памятью, чтобы правильно использовать слабые ссылки.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Нужен человек, для сбора вопросов из собеседований на должность iOS разработчик.
Что надо делать:
1. Смотреть записи собеседований (список будет дан)
2. Выписывать вопросы, которые задают кандидату
Ставка: 450 руб. / час
Примерная ЗП: 54 000 руб. / месяц (4 часа в день)
Если интересно и можешь уделять работе от 4 часов / день, то отправь сообщение и сразу напиши какие языки программирования знаешь и какие лучше всего?
Что надо делать:
1. Смотреть записи собеседований (список будет дан)
2. Выписывать вопросы, которые задают кандидату
Ставка: 450 руб. / час
Примерная ЗП: 54 000 руб. / месяц (4 часа в день)
Если интересно и можешь уделять работе от 4 часов / день, то отправь сообщение и сразу напиши какие языки программирования знаешь и какие лучше всего?
В разработке и программировании в целом
Message (или Message Passing) может использоваться в различных контекстах, не только при тестировании. Передача сообщений используется для имитации взаимодействий между объектами, проверки их поведения и создания мок-объектов. Использование XCTest для создания мок-объектов и проверки вызова методов.
class MockService: Service {
var didCallMethod = false
func someMethod() {
didCallMethod = true
}
} Используется для передачи сообщений от одного объекта к другому, часто через протоколы. Это позволяет одному объекту уведомлять другой о произошедших событиях. Использование делегатов в UITableView.
protocol TableViewDelegate: AnyObject {
func didSelectRow(at indexPath: IndexPath)
}
class TableView: UIView {
weak var delegate: TableViewDelegate?
// код для обработки выбора строки
} Используется для передачи сообщений между различными частями приложения. Это позволяет объектам взаимодействовать, не зная друг о друге. Отправка и получение уведомлений.
NotificationCenter.default.post(name: .someNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: .someNotification, object: nil)
Позволяют передавать логические блоки кода как аргументы функций или методов. Это часто используется для обратных вызовов. Использование клоужеров для асинхронных операций.
func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {
// код для получения данных
completion(.success(data))
} Передача сообщений между различными процессами или приложениями, часто через специфические API и фреймворки. Использование XPC для общения между процессами.
let connection = NSXPCConnection(serviceName: "com.example.service")
connection.remoteObjectInterface = NSXPCInterface(with: ExampleProtocol.self)
Использование акторов и очередей для безопасной передачи сообщений между потоками. Использование DispatchQueue для выполнения задач асинхронно.
DispatchQueue.global().async {
// Асинхронная задача
DispatchQueue.main.async {
// Обновление UI
}
} Передача сообщений между клиентом и сервером с использованием протоколов HTTP, WebSocket и т.д. Использование URLSession для выполнения сетевых запросов.
let url = URL(string: "https://example.com/api")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
// обработка ответа
}
task.resume()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM