Kas pārkāpj izvēles funkciju protokolā?
sobes.tech AI
Atbilde no AI
Prasību pievienošana protokolam pēc tam, kad to sāka izmantot citi moduļi vai bibliotēkas. Ja protokols jau ir pieņemts un īstenots, parasto (neopcionālo) metožu vai īpašību pievienošana radīs kompilācijas kļūdas visās vietās, kur tiek izmantots protokols, līdz šiem jauniem prasībām tiks izpildīts:
Opciju prasības ļauj paplašināt protokolus, neietekmējot esošo īstenošanu. Klases vai struktūras var īstenot tikai daļu opciju metožu. Tas ir noderīgi, strādājot ar deleģentiem vai pievienojot jaunas funkcijas jau izveidotam API:
Piemērs ar Objective-C protokolu (jo Swift nepārstāv @optional bez @objc):
// Swiftā `@optional` tiek izmantots ar `@objc` protokolu
import Foundation
@objc protocol MyDelegate {
func requiredMethod() -> Bool
@optional func optionalMethod1()
@optional func optionalMethod2(value: Int)
}
class MyClass {
weak var delegate: MyDelegate?
func doSomething() {
if delegate?.requiredMethod() == true {
// Opciju metožu izsaukšana ar pārbaudi
delegate?.optionalMethod1?()
if let delegate = delegate {
if delegate.responds(to: #selector(delegate.optionalMethod2(value:))) {
delegate.optionalMethod2?(value: 10)
}
}
}
}
}
Swift tīri protokoli (bez @objc) neatbalsta @optional. Lai būtu opciju prasības, protokols jāmarķē kā @objc. Šādi protokoli var tikt paplašināti, pievienojot noklusējuma īstenojumus opciju metodēm, kas ir mūsdienīgāks pieejas veids Swift:
Piemērs ar protokolu paplašinājumiem Swift:
// Modernāks pieejas veids: protokolu paplašinājumi ar noklusējuma īstenojumiem
protocol MyProtocol {
func requiredMethod() -> Bool
func optionalMethod1()
func optionalMethod2(value: Int)
}
// Noklusējuma īstenojumi opciju metodēm
extension MyProtocol {
func optionalMethod1() {
// Noklusējuma īstenojums vai standarta uzvedība
print("Optional method 1 default implementation")
}
func optionalMethod2(value: Int) {
// Noklusējuma īstenojums
print("Optional method 2 default implementation with value: \(value)")
}
}
class MyClassSwift {
var delegate: MyProtocol?
func doSomething() {
if delegate?.requiredMethod() == true {
// Metodes tiek izsauktas bez pārbaudes par nil, jo tās
// vai ir īstenotas klasē/struktūrā, vai tiek izmantots
// paplašinājuma īstenojums
delegate?.optionalMethod1()
delegate?.optionalMethod2(value: 20)
}
}
}
class MyCustomDelegate: MyProtocol {
func requiredMethod() -> Bool {
print("Required method implemented")
return true
}
// opciju metodes nav obligāti īstenojamas,
// tiks izmantots noklusējuma īstenojums no paplašinājuma.
// Bet tās var pārdefinēt, ja nepieciešams citādāks uzvedības:
// func optionalMethod1() {
// print("Custom implementation of optional method 1")
// }
}
let customDelegate = MyCustomDelegate()
let myClassSwift = MyClassSwift()
myClassSwift.delegate = customDelegate
myClassSwift.doSomething()
Tādējādi, mēģinājums pievienot jaunu obligātu prasību jau esošam protokolam, kas tiek izmantots kodā, pārkāpj atpakaļ saderību. Opciju prasības (caur @objc vai, vēlams, caur protokolu paplašinājumiem) to novērš.