Irbisa · Шпаргалка
Swift: ООП и протоколы
Классы, struct, enum, протоколы, расширения, protocol-oriented programming
Чем структура отличается от класса в Swift?
Назовите основные принципы ООП и покажите, как каждый из них выражается в Swift.
Чем перегрузка (overloading) отличается от переопределения (overriding), и что может переопределить подкласс?
class Shape { var name: String { "shape" } func area() -> Double { 0 } final func describe() -> String { "\(name): \(area())" }}…Что такое протокол в Swift и чем он отличается от интерфейса или абстрактного класса?
protocol Named { var name: String { get } // a let or a var satisfies it} protocol Greeter: Named { // protocol inheritance var greeting: String { get set } // needs something writable…Чем raw values отличаются от associated values в enum Swift?
enum HTTPStatus: Int { case ok = 200, notFound = 404}let status = HTTPStatus(rawValue: 404) // Optional(.notFound)print(HTTPStatus.ok.rawValue) // 200…Что можно добавить к типу через extension в Swift, а что нельзя?
extension String { var isBlank: Bool { trimmingCharacters(in: .whitespacesAndNewlines).isEmpty }} extension Array where Element: Numeric { // constrained extension func sum() -> Element { reduce(0, +) }…Какие уровни доступа есть в Swift и чем
publicотличается отopen?// Inside a framework moduleopen class BaseViewController { // apps may subclass and override open func configure() {}} public class Logger { // apps may use, not subclass…Что такое
lazy-свойство, чем оно отличается от вычисляемого и наблюдаемого свойства и может ли оно вычислиться больше одного раза?final class ProfileHeader { var name: String { willSet { print("about to show \(newValue)") } didSet { guard name != oldValue else { return } // observers fire even for equal values setNeedsLayout()…Что делает
mutatingи почему методам структуры он нужен, а методам класса нет?struct Counter { private(set) var value = 0 mutating func bump() { value += 1 }} enum Step {…Что требуют
EquatableиHashableи что произойдёт, если у двух разных значений одинаковый хэш?struct Tag: Hashable { // == and hash(into:) synthesized let name: String let colorHex: String} struct User: Hashable, Identifiable {…Это объявление делегата не компилируется. Какая ошибка и как её исправить?
protocol DownloaderDelegate { func downloader(_ downloader: Downloader, didFinish text: String)} final class Downloader { weak var delegate: DownloaderDelegate? func finish(with text: String) { delegate?.downloader(self, didFinish: text) }}Что такое
deinit, когда он вызывается и в каком потоке выполняется?final class ImageLoader { private var task: Task<Void, Never>? func start() { task = Task { /* download */ } } deinit {…Чем отличаются
static- иclass-члены и что меняетfinal?class Formatter { static func make() -> Formatter { Formatter() } // cannot be overridden class var kind: String { "generic" } // subclasses may override // class var cache = 0 // error: class stored properties not supported}…Как устроена инициализация классов в Swift: designated и convenience-инициализаторы, две фазы и failable-инициализаторы?
class Vehicle { let wheels: Int var name: String init(wheels: Int, name: String) { // designated: own properties, then up self.wheels = wheels…Что такое протокол-ориентированное программирование и чем оно отличается от наследования классов?
protocol Loggable { var label: String { get } } extension Loggable { func log() { print(label) }}…Что выведет этот код и почему два вызова ведут себя по-разному?
protocol Greeter { func greet() -> String} extension Greeter { func greet() -> String { "default greet" } func shout() -> String { "default shout" }}struct Robot: Greeter { func greet() -> String { "beep" } func shout() -> String { "BEEP" }} let robot: any Greeter = Robot()print(robot.greet())print(robot.shout())Могут ли у протокола в Swift быть необязательные методы? Сравните
@objc optionalи реализацию по умолчанию.@objc protocol ChartDataSource { func numberOfPoints() -> Int @objc optional func title() -> String // may be missing} final class SalesChart: NSObject, ChartDataSource {…Почему эта структура не компилируется и как вместо неё смоделировать связный список или дерево?
struct Node { let value: Int var next: Node?} var head = Node(value: 1, next: Node(value: 2, next: nil))Когда варианты лучше моделировать через enum с associated values, а когда через протокол и отдельный тип на каждый вариант?
Найдите баг: после обновления 2.3 заказы, закэшированные предыдущей версией, показывают неверный статус.
enum OrderStatus: Int, Codable { case draft // added in 2.3 case paid case shipped case delivered} struct Order: Codable { let id: Int var status: OrderStatus} // Orders are cached on disk between launchesfunc loadCachedOrder(from data: Data) throws -> Order { try JSONDecoder().decode(Order.self, from: data)}Почему не-final класс должен помечать инициализатор, выполняющий требование
initиз протокола, какrequired?protocol Buildable { init(id: String)} class Node: Buildable { let id: String…Как устроена диспетчеризация методов в Swift (static, vtable, witness table и message dispatch) и сколько стоит каждая?
Найдите баг: pull-to-refresh вызывает
refreshAll, но экран ленты так и не перезагружается.@MainActor protocol Refreshable: AnyObject { func refresh()}extension Refreshable { func refresh() {} // default: nothing to reload} class BaseViewController: UIViewController, Refreshable {} final class FeedViewController: BaseViewController { func refresh() { reloadFeed() }} @MainActor func refreshAll(_ screens: [any Refreshable]) { screens.forEach { $0.refresh() }}Тип соответствует двум протоколам, и каждый даёт свою реализацию
refresh()по умолчанию. Что сделает Swift и как разрешить конфликт?protocol Reloadable { func refresh() }protocol Pollable { func refresh() }extension Reloadable { func refresh() { print("from cache") } }extension Pollable { func refresh() { print("from network") } } struct Feed: Reloadable, Pollable {…