Нужен человек, для сбора вопросов из собеседований на должность 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
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Это концепция в разработке на платформе Apple (iOS, macOS), которая позволяет бесшовно использовать объекты из Core Foundation (C) в Swift или Objective-C и наоборот без затрат на преобразование. Это означает, что определенные типы данных из Core Foundation и соответствующие классы Foundation взаимозаменяемы.
Core Foundation: Фреймворк C, предоставляющий основные типы данных и службы.
Foundation: Фреймворк Objective-C и Swift, предоставляющий более высокоуровневые API.
Позволяет использовать объекты Core Foundation в API, ожидающих объекты Foundation, и наоборот.
Эти типы взаимозаменяемы, что позволяет использовать их взаимозаменяемо в функциях и методах.
let cfString: CFString = "Hello, World!" as CFString
let nsString: NSString = cfString as NSString
Эти типы также могут использоваться взаимозаменяемо.
let cfArray: CFArray = ["One", "Two", "Three"] as CFArray
let nsArray: NSArray = cfArray as NSArray
Взаимозаменяемость этих типов позволяет легко переключаться между ними.
let cfDictionary: CFDictionary = ["key": "value"] as CFDictionary
let nsDictionary: NSDictionary = cfDictionary as NSDictionary
Упрощает использование и интеграцию старых API Core Foundation с новыми API Foundation.
Отсутствие затрат на преобразование типов улучшает производительность.
Обеспечивает совместимость между кодом, написанным на C, Objective-C и Swift.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Это файл, содержащий отладочную информацию, используемую для сопоставления адресов в машинном коде с исходным кодом. В iOS и macOS разработке dSYM-файлы играют важную роль в процессе отладки и анализа сбоев (crash reports).
dSYM-файл содержит символы отладки, такие как имена методов и классов, которые соответствуют машинному коду скомпилированного приложения. Эта информация позволяет разработчикам интерпретировать сбои и ошибки, связывая их с исходным кодом.
dSYM-файлы автоматически создаются Xcode при сборке приложения. Они хранятся в специальной директории и могут быть включены в архив сборки (archive) для последующей загрузки в инструменты анализа сбоев.
Декодирование отчетов о сбоях: При сбое приложения, отчет о сбое содержит машинные адреса, которые трудно интерпретировать без символов отладки. dSYM-файл помогает преобразовать эти адреса в понятные строки исходного кода.
Инструменты анализа: Инструменты, такие как Xcode, Crashlytics, или другие платформы сбора и анализа сбоев, используют dSYM-файлы для декодирования и анализа отчетов о сбоях.
Отчеты о сбоях можно получить из Xcode, TestFlight, App Store Connect, или от пользователей.
Сервис анализа сбоев, такой как Crashlytics, запрашивает загрузку соответствующего dSYM-файла для декодирования отчетов. Обычно это можно сделать через интерфейс разработчика или автоматически при настройке сборочного процесса.
С помощью dSYM-файла отчет о сбое преобразуется в читаемый формат, содержащий строки исходного кода, где произошел сбой.
Всегда сохраняйте dSYM-файлы для каждой версии вашего приложения, так как они уникальны для каждой сборки.
Храните dSYM-файлы в безопасном месте (например, в системе управления версиями), чтобы всегда иметь доступ к нужной информации для анализа сбоев.
Убедитесь, что используемый dSYM-файл соответствует версии приложения, из которой получен отчет о сбое.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Sitable появляется в качестве новой функции, когда объект или пространство становится подходящим для использования. Это происходит благодаря изменению условий, которые делают его удобным или доступным. Например, помещение может стать sitable после установки мебели или проведения ремонта.
Файл с отладочной информацией для декодирования отчетов о сбоях. Он связывает машинный код с исходным кодом.
Имена методов и классов.
Декодирование отчетов о сбоях.
Пример:
Взаимозаменяемое использование объектов Core Foundation и Foundation в Swift и Objective-C без преобразования.
Связь: Использование объектов Core Foundation и Foundation.
Примеры:
CFStringRef и NSStringCFArrayRef и NSArrayCFDictionaryRef и NSDictionaryUITableView
let tableView = UITableView()
tableView.dataSource = self
UICollectionView
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.dataSource = self
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Wick-ссылки являются прямыми и предотвращают удаление объекта сборщиком мусора, тогда как Anound-ссылки являются слабыми и позволяют сборщику мусора удалить объект при отсутствии других прямых ссылок.
Слабая ссылка не удерживает объект в памяти. Объект может быть освобожден, если на него нет других сильных ссылок. Может быть nil. Используется с
Optional типами. Автоматически становится nil, когда объект освобождается. Для объектов, которые могут исчезнуть во время жизненного цикла.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 Неактивная ссылка не удерживает объект в памяти и не может быть nil. Никогда не бывает nil. Используется с
non-Optional типами. Программа крашнется при попытке доступа к освобожденному объекту. Для объектов, которые должны существовать на протяжении всего жизненного цикла другого объекта.class Person {
var name: String
var apartment: Apartment?
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!) Weak: Может быть nil.
Unowned: Никогда не бывает nil.
Weak: Используется, когда объект может быть освобожден во время жизненного цикла.
Unowned: Используется, когда объект должен существовать столько же, сколько и его владелец.
Weak: Для делегатов и объектов, которые могут исчезнуть.
Unowned: Для циклических зависимостей, где один объект гарантированно существует.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
В Swift объекты классов и структуры имеют различия в управлении памятью и способе обращения.
Являются ссылочными типами, что означает, что объекты классов передаются по ссылке.
Создание
class Person {
var name: String
init(name: String) {
self.name = name
}
}
let person1 = Person(name: "Alice")
let person2 = person1 // person2 указывает на тот же объект, что и person1 Изменение свойств
person2.name = "Bob"
print(person1.name) // "Bob"
Являются значимыми типами, что означает, что объекты структур передаются по значению.
Создание
struct Person {
var name: String
}
var person1 = Person(name: "Alice")
var person2 = person1 // person2 является копией person1Изменение свойств
person2.name = "Bob"
print(person1.name) // "Alice"
Классы передаются по ссылке. Изменения через одну ссылку отражаются на всех ссылках.
Структуры передаются по значению. Каждое присваивание или передача создает копию.
Классы: Используются для объектов, которым требуется идентичность или наследование.
Структуры: Используются для простых данных, которые логически являются значениями, таких как точки, размеры или пользовательские данные.
Классы
class Car {
var model: String
init(model: String) {
self.model = model
}
}
let car1 = Car(model: "Tesla")
let car2 = car1
car2.model = "BMW"
print(car1.model) // "BMW"Структуры
struct Car {
var model: String
}
var car1 = Car(model: "Tesla")
var car2 = car1
car2.model = "BMW"
print(car1.model) // "Tesla"Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это концепции, которые используются для поддержки полиморфизма и динамического диспетчеризации методов.
Это структура данных, используемая компилятором Swift для обеспечения полиморфизма при работе с протоколами. Она содержит указатели на функции, реализующие требования протокола для конкретного типа. Это позволяет динамически вызывать методы протокола на объекте, даже если точный тип объекта неизвестен.
Протоколы определяют интерфейс (набор методов и свойств), который должен быть реализован типом. Когда тип соответствует протоколу, компилятор создает таблицу свидетельств для этого типа.
Таблица свидетельств содержит указатели на реализации методов и свойств, определенных в протоколе. При вызове метода протокола через объект типа, соответствующего протоколу, используется таблица свидетельств для динамического поиска и вызова правильного метода.
Swift использует таблицы свидетельств для реализации динамического полиморфизма, позволяя вызывать методы протокола на объектах различных типов. Это обеспечивает гибкость и расширяемость кода.
Определение протокола и соответствующего типа
protocol Drawable {
func draw()
}
class Circle: Drawable {
func draw() {
print("Drawing a circle")
}
}
class Square: Drawable {
func draw() {
print("Drawing a square")
}
}
func render(shape: Drawable) {
shape.draw() // Использование таблицы свидетельств для вызова правильного метода draw()
}
let shapes: [Drawable] = [Circle(), Square()]
for shape in shapes {
render(shape: shape)
}Таблицы свидетельств позволяют Swift поддерживать полиморфизм через протоколы.
Они обеспечивают динамическую диспетчеризацию методов, что позволяет вызывать методы на объектах различных типов, соответствующих одному протоколу.
Использование таблиц свидетельств позволяет оптимизировать вызовы методов и улучшить производительность по сравнению с другими методами динамической диспетчеризации.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это упорядоченная коллекция элементов одного типа. Массивы являются одним из основных и наиболее часто используемых типов данных в Swift. Они предоставляют множество методов и свойств для управления и обработки коллекций данных.
Пустой массив
var emptyArray: [Int] = []
var anotherEmptyArray = [Int]()
Массив с начальными значениями
var numbers: [Int] = [1, 2, 3, 4, 5]
var moreNumbers = [1, 2, 3, 4, 5]
По индексу
let firstNumber = numbers[0] // 1
Изменение элемента
numbers[0] = 10 // теперь numbers = [10, 2, 3, 4, 5]
В конец массива
numbers.append(6) // теперь numbers = [10, 2, 3, 4, 5, 6]
Вставка по индексу
numbers.insert(7, at: 1) // теперь numbers = [10, 7, 2, 3, 4, 5, 6]
По индексу
numbers.remove(at: 1) // теперь numbers = [10, 2, 3, 4, 5, 6]
Последний элемент
numbers.removeLast() // теперь numbers = [10, 2, 3, 4, 5]
Все элементы
numbers.removeAll() // теперь numbers = []
С использованием цикла
forfor number in numbers {
print(number)
} С использованием метода
forEachnumbers.forEach { print($0) } Фильтрация
let evenNumbers = numbers.filter { $0 % 2 == 0 } Преобразование
let stringNumbers = numbers.map { String($0) }
let sum = numbers.reduce(0, +)
Элементы хранятся в определенном порядке и доступ к ним возможен по индексу.
Легко добавлять и удалять элементы, изменять их порядок.
Массивы предоставляют множество методов для обработки данных, таких как фильтрация, сортировка, преобразование и т.д.
Все элементы массива должны быть одного типа, что обеспечивает безопасность типов.
Доступ по индексу выполняется за постоянное время O(1), но вставка и удаление элементов могут иметь сложность O(n), если они происходят не в конце массива.
Если массив объявлен с использованием
let, он становится неизменяемым, и его элементы нельзя добавлять или удалять. let immutableNumbers = [1, 2, 3]
// immutableNumbers.append(4) // Ошибка: Невозможно изменить неизменяемый массив
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Это механизм в iOS и macOS для обмена сообщениями между различными частями приложения. Он позволяет объектам отправлять и получать уведомления без необходимости напрямую ссылаться друг на друга, что способствует более гибкому и модульному дизайну.
Любой объект может отправить уведомление с помощью Notification Center. Уведомления идентифицируются по имени (
Notification.Name). Можно передать дополнительную информацию в виде словаря (userInfo).NotificationCenter.default.post(name: .myNotification, object: nil)
Объекты могут регистрироваться для получения уведомлений с определенным именем. Для обработки уведомлений используется метод, который будет вызван при получении уведомления.
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: .myNotification, object: nil)
@objc func handleNotification(notification: Notification) {
print("Received notification")
}
Важно удалять наблюдателей, когда они больше не нужны, чтобы избежать утечек памяти. Обычно это делается в методе
deinit или перед уничтожением объекта.NotificationCenter.default.removeObserver(self, name: .myNotification, object: nil)
Объекты не нужно напрямую ссылаться друг на друга, что улучшает модульность кода.
Позволяет легко организовать обмен сообщениями между различными частями приложения.
Уведомления могут использоваться многими объектами, что облегчает реализацию функций, таких как обновление интерфейса или реагирование на события.
Когда данные изменяются, можно отправить уведомление для обновления пользовательского интерфейса.
NotificationCenter.default.post(name: .dataDidUpdate, object: nil)
Например, можно подписаться на уведомление о смене состояния сети.
NotificationCenter.default.addObserver(self, selector: #selector(handleNetworkChange), name: .reachabilityChanged, object: nil)
Различные модули приложения могут общаться друг с другом через Notification Center, не создавая сильных зависимостей.
NotificationCenter.default.post(name: .userDidLogin, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateUI), name: .userDidLogin, object: nil)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Метод
loadView() в UIViewController отвечает за создание и инициализацию основного представления (view) контроллера. Обычно этот метод используется в специфических случаях, когда требуется полное управление процессом создания представления. Когда необходимо создать и настроить представление программно без использования Interface Builder (storyboards или xibs).
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.text = "Hello, World!"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
self.view = view
} Когда требуется экономить память, загружая представление только при его необходимости, а не при инициализации контроллера. Этот подход позволяет уменьшить использование памяти, особенно в случае сложных или тяжелых представлений.
Когда интерфейс зависит от динамических данных или состояния, доступного только в рантайме. Например, создание различных представлений в зависимости от конфигурации, полученной из сети или другого источника.
Когда требуется специфическая настройка представления, которая не может быть выполнена через Interface Builder. Например, создание представлений с использованием сторонних библиотек или компонентов, которые требуют программного конфигурирования.
В методе
loadView() обязательно должно быть присвоено значение свойству self.view, иначе возникнет ошибка и контроллер не будет иметь основного представления. override func loadView() {
self.view = UIView()
} Рекомендуется минимизировать количество кода в
loadView(), переместив дополнительную настройку представления в метод viewDidLoad() или другие соответствующие методы жизненного цикла.Не выполняйте ресурсоемкие операции в
loadView(), чтобы не замедлять создание представления. Это может негативно повлиять на производительность.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Минимальная логика и количество экранов. Одностраничные приложения. Быстрая разработка.
Быстрое создание прототипов. Демонстрация идей заказчику. Легкость реализации.
Приложения с простой функциональностью. Калькуляторы, справочники. Простота поддержки.
Изучение основ iOS-разработки. Учебные проекты. Понятность для новичков.
Работа с существующими проектами на MVC. Доработка старого кода. Сохранение целостности архитектуры.
Данные и бизнес-логика.
struct User {
let name: String
} Отображение данных (Storyboards, xibs).
@IBOutlet weak var nameLabel: UILabel!
Управление взаимодействием между Model и View.
class ViewController: UIViewController {
var user: User?
override func viewDidLoad() {
super.viewDidLoad()
user = User(name: "Alice")
updateView()
}
func updateView() {
nameLabel.text = user?.name
}
} Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM