في Swift ، عند تعلم UI (واجهة المستخدم) ، عاجلاً أم آجلاً ، يحتاج الجميع إلى استخدام مفوض. تكتب جميع الأدلة عنهم ، ويبدو أنك تفعل كما هو مكتوب هناك ، ويبدو أنه يعمل ، ولكن لماذا وكيف يعمل ، لا يناسب كل شخص في رؤوسهم حتى النهاية. شخصيًا ، شعرت لفترة من الوقت أن المندوب هو نوع من الكلمات السحرية ، وأنه مدمج مباشرة في لغة البرمجة (وهذا هو مدى إرباك أفكاري من هذه الأدلة). دعنا نحاول شرح ما هو بعبارات بسيطة. وبمجرد فهمك للمفوض ، سيكون من الأسهل بكثير فهم ماهية رد الاتصال وكيف يعمل.
النادل والطاهي
لذا ، قبل الانتقال إلى الكود ، دعونا نتخيل نادلًا معينًا وطاهيًا ما. تلقى النادل طلبًا من العميل على الطاولة ، لكنه هو نفسه لا يعرف كيف يطبخ ، ويحتاج إلى سؤال الطباخ عن ذلك. يمكنه أن يذهب إلى المطبخ ويقول للطاهي ، "اطبخ الدجاج". يمتلك الطباخ الأدوات المناسبة (مقلاة ، زيت ، نار ...) ومهارة الطبخ. يحضر الطباخ ويعطي الطبق للنادل. يأخذ النادل ما صنعه الشيف ويحضره للعميل.
الآن دعنا نتخيل موقفًا لا يستطيع فيه النادل القدوم إلى المطبخ وإخبار الطباخ مباشرة بالطبق الذي تم طلبه منه. لا يسمحون له بالدخول إلى المطبخ (على سبيل المثال ، مثل هذه القواعد) أو المطبخ في طابق آخر (لقد سئمت من الجري). والطريقة الوحيدة للتواصل هي من خلال نافذة المصعد الصغير. يضع النادل ملاحظة هناك ، ويضغط على الزر ، ويذهب المصعد إلى المطبخ. يأتي مع طبق معد. هل تذكر؟ الآن ، دعنا نصلح الموقف في رؤوسنا ، ونحاول إعادة إنشائه من خلال الكود وفهم كيفية ارتباط ذلك بموضوعنا.
دعنا ننتقل إلى الكود
نصنع دروس النادل والطبخ. من أجل التبسيط ، دعنا نفعل ذلك في الملعب:
import UIKit
//
class Waiter {
/// "" - . , "private".
private var order: String?
/// " ".
func takeOrder(_ food: String) {
print("What would you like?")
print("Yes, of course!")
order = food
sendOrderToCook()
}
/// " ". . ?
private func sendOrderToCook() {
// ??? ?
}
/// " ". .
private func serveFood() {
print("Your \(order!). Enjoy your meal!")
}
}
//
class Cook {
/// "". .
private let pan: Int = 1
/// "". .
private let stove: Int = 1
/// "". .
private func cookFood(_ food: String) -> Bool {
print("Let's take a pan")
print("Let's put \(food) on the pan")
print("Let's put the pan on the stove")
print("Wait a few minutes")
print("\(food) is ready!")
return true
}
}
الآن نقوم بإنشاء نسخ منها (نوظفهم للعمل) ، ونطلب من النادل استلام الطلب (دجاجة):
// ( ):
let waiter = Waiter()
let cook = Cook()
// . , :
waiter.takeOrder("Chiken")
كيف يمكن للنادل أن يخبر الطباخ بما يجب طهيه الآن؟
, , private. private, :
cook.cookFood(waiter.order!)
// 'cookFood' is inaccessible due to 'private' protection level
// 'order' is inaccessible due to 'private' protection level
«» , private . "" , ? : " , , ?"
"". . . "" " ":
protocol InterchangeViaElevatorProtocol {
func cookOrder(order: String) -> Bool
}
, "", , . . , . : , .
, . ().
. , , " ". Xcode . Bool .
cookFood, .
extension Cook: InterchangeViaElevatorProtocol {
func cookOrder(order: String) -> Bool {
cookFood(order)
}
}
" ". , , .
extension Waiter {
var receiverOfOrderViaElevator: InterchangeViaElevatorProtocol? { return cook }
}
, . return cook.
-: , . .
, . , .
:
import UIKit
protocol InterchangeViaElevatorProtocol {
func cookOrder(order: String) -> Bool
}
class Waiter {
// " ". , , .
var receiverOfOrderViaElevator: InterchangeViaElevatorProtocol?
var order: String?
func takeOrder(_ food: String) {
print("What would you like?")
print("Yes, of course!")
order = food
sendOrderToCook()
}
private func sendOrderToCook() {
// ??? ?
}
private func serveFood() {
print("Your \(order!). Enjoy your meal!")
}
}
//
class Cook: InterchangeViaElevatorProtocol {
private let pan: Int = 1
private let stove: Int = 1
private func cookFood(_ food: String) -> Bool {
print("Let's take a pan")
print("Let's put \(food) on the pan")
print("Let's put the pan on the stove")
print("Wait a few minutes")
print("\(food) is ready!")
return true
}
// , ():
func cookOrder(order: String) -> Bool {
cookFood(order)
}
}
private order ( ).
:
- :
// :
let waiter = Waiter()
let cook = Cook()
// :
waiter.takeOrder("Chiken")
, " " – .
// , " " - :
waiter.receiverOfOrderViaElevator = cook
, , , .
" " :
// " " :
waiter.receiverOfOrderViaElevator?.cookOrder(order: waiter.order!)
, !
/*
What would you like?
Yes, of course!
Let's take a pan
Let's put Chiken on the pan
Let's put the pan on the stove
Wait a few minutes
Chiken is ready!
*/
« », .
«» , « », , .
private func sendOrderToCook() {
// cookOrder " ":
receiverOfOrderViaElevator?.cookOrder(order: order!)
}
! receiverOfOrderViaElevator, . . delegate, . , , .
? «, – . – UI?»
delegate UI?
UI , «» «». , table view collection view. table view collection view : . . () «» («Delegate»).
, Delegable «». , , !
, – . . Waiter. () hireWaiter. (, -):
// -
class Chief: InterchangeViaElevatorProtocol {
private let pan: Int = 1
private let stove: Int = 1
private func cookFood(_ food: String) -> Bool {
print("Let's take a pan")
print("Let's put \(food) on the pan")
print("Let's put the pan on the stove")
print("Wait a few minutes")
print("\(food) is ready!")
return true
}
// , ():
func cookOrder(order: String) -> Bool {
cookFood(order)
}
// - :
func hireWaiter() -> Waiter {
return Waiter()
}
}
- ( - hireWaiter):
// - (- ):
let chief = Chief()
// - :
let waiter = chief.hireWaiter()
// :
waiter.takeOrder("Chiken")
. , " " – -. .
// , " " - -:
waiter.receiverOfOrderViaElevator = chief
// " " :
waiter.receiverOfOrderViaElevator?.cookOrder(order: waiter.order!)
, .
. , -, , « » -.
class SmartChief: Chief {
override func hireWaiter() -> Waiter {
let waiter = Waiter()
waiter.receiverOfOrderViaElevator = self //
return waiter
}
}
SmartChief Chief .
, - (), . !
let smartChief = SmartChief()
let smartWaiter = smartChief.hireWaiter()
smartWaiter.takeOrder("Fish")
/*
What would you like?
Yes, of course we have Fish!
Let's take a pan
Let's put Fish on the pan
Let's put the pan on the stove
Wait a few minutes
Fish is ready!
*/
:
- (), , , , - .
- «» .
- (, ) , ( )
- , self «» .
, «» , , .
. , ! .
(, callback). ? ,
, , «» . , . ? ?
(callback) – , . . .
-,
, - ( , ). , , : «- ! , !» , , . .
.
. . , String Bool. cookFood ! - - .
///
class TalentedWaiter {
var order: String?
// . , String Bool.
var doEverything: ((String) -> Bool)?
func takeOrder(_ food: String) {
print("What would you like?")
print("Yes, of course we have \(food)!")
order = food
// - :
doOwnself()
}
private func doOwnself() -> Bool {
// , :
if let doEverything = doEverything {
let doOwnself = doEverything(order!)
return doOwnself
} else {
return false
}
}
}
-. , , . , . , :
// -
class LazyChief {
private let pan: Int = 1
private let stove: Int = 1
private func cookFood(_ food: String) -> Bool {
print("I have \(pan) pan")
print("Let's put \(food) on the pan!")
print("I have \(stove) stove. Let's put the pan on the stove!")
print("Wait a few minutes...")
print("\(food) is ready!")
return true
}
// :
func hireWaiter() -> TalentedWaiter {
let talentedWaiter = TalentedWaiter()
// . , cookFood:
talentedWaiter.doEverything = { order in
self.cookFood(order)
}
return talentedWaiter
}
}
-, , , :
let lazyChief = LazyChief()
let talentedWaiter = lazyChief.hireWaiter()
talentedWaiter.takeOrder("Meat")
/*
What would you like?
Yes, of course we have Meat!
I have 1 pan
Let's put Meat on the pan!
I have 1 stove. Let's put the pan on the stove!
Wait a few minutes...
Meat is ready!
*/
, , «» .
, , . , , ().
– . , self , - , .
[weak self] in . , !
talentedWaiter.doEverything = { [weak self] order in
self!.cookFood(order)
}
. , . !