مندوبون سريعون وعمليات رد نداء بلغة واضحة. ما هو هذا المفوض وكيف يعمل رد الاتصال؟

في 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 ( ).



:



  1. :


//      :
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!
 */


:



  1. (), , , , - .
  2. «» .
  3. (, ) , ( )
  4. , 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)
        }


. , . !



GitHub




All Articles