ผู้ได้รับมอบหมายอย่างรวดเร็ว?


134

เราจะสร้างตัวแทนได้อย่างไรเช่นNSUserNotificationCenterDelegateรวดเร็ว?


4
คุณหมายถึงการใช้ตัวแทนหรือการกำหนดผู้รับมอบสิทธิ์ของคุณเอง?
drewag

คำตอบ:


72

ไม่ต่างจาก obj-c ขั้นแรกคุณต้องระบุโปรโตคอลในการประกาศคลาสของคุณดังต่อไปนี้:

class MyClass: NSUserNotificationCenterDelegate

การใช้งานจะมีลักษณะดังนี้:

// NSUserNotificationCenterDelegate implementation
func userNotificationCenter(center: NSUserNotificationCenter, didDeliverNotification notification: NSUserNotification) {
    //implementation
}

func userNotificationCenter(center: NSUserNotificationCenter, didActivateNotification notification: NSUserNotification) {
    //implementation
}

func userNotificationCenter(center: NSUserNotificationCenter, shouldPresentNotification notification: NSUserNotification) -> Bool {
    //implementation
    return true
}

แน่นอนคุณต้องตั้งผู้รับมอบสิทธิ์ ตัวอย่างเช่น:

NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self;

1
จะเกิดอะไรขึ้นเมื่อคุณต้องการขยาย UIViewController ตัวอย่างเช่นในวัตถุประสงค์ -c คุณสามารถมีบางอย่างที่โกหกสิ่งนี้@interface MyCustomClass: UIViewController <ClassIWantToUseDelegate>ทำให้คุณสามารถเริ่ม / กำหนดค่าตัวควบคุมมุมมองรวมถึงเรียกวิธีการมอบหมายในมุมมองย่อยได้ อะไรทำนองนี้ ?
Mahmud Ahmad

1
สวัสดีอดัมคำถามสั้น ๆ ฉันจะตั้งค่า delegate = self ได้อย่างไรถ้าฉันไม่สามารถสร้างอินสแตนซ์อ็อบเจ็กต์ได้เนื่องจากเป็นคลาสทั่วไปที่ฉันไม่สามารถเข้าถึงได้ในคลาสอื่น แต่ฉันต้องการให้คลาส generics เรียกใช้ฟังก์ชันใน ชั้นเรียนอื่นจึงจำเป็นต้องมีผู้ร่วมประชุม?
มาริน

236

ต่อไปนี้เป็นความช่วยเหลือเล็กน้อยสำหรับผู้ร่วมประชุมระหว่างตัวควบคุมมุมมองสองตัว:

ขั้นตอนที่ 1:สร้างโปรโตคอลใน UIViewController ที่คุณจะลบ / จะส่งข้อมูล

protocol FooTwoViewControllerDelegate:class {
    func myVCDidFinish(_ controller: FooTwoViewController, text: String)
}

ขั้นที่ 2: ประกาศผู้รับมอบสิทธิ์ในคลาสการส่ง (เช่น UIViewcontroller)

class FooTwoViewController: UIViewController {
    weak var delegate: FooTwoViewControllerDelegate?
    [snip...]
}

ขั้นตอนที่ 3: ใช้ผู้รับมอบสิทธิ์ในวิธีการคลาสเพื่อส่งข้อมูลไปยังวิธีการรับซึ่งเป็นวิธีการใด ๆ ที่ใช้โปรโตคอล

@IBAction func saveColor(_ sender: UIBarButtonItem) {
        delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
}

ขั้นตอนที่ 4:ใช้โปรโตคอลในคลาสรับ

class ViewController: UIViewController, FooTwoViewControllerDelegate {

ขั้นตอนที่ 5:ใช้วิธีการมอบสิทธิ์

func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
    colorLabel.text = "The Color is " +  text
    controller.navigationController.popViewController(animated: true)
}

ขั้นตอนที่ 6:ตั้งค่าผู้รับมอบสิทธิ์ในการจัดเตรียมสำหรับเซก:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "mySegue" {
        let vc = segue.destination as! FooTwoViewController
        vc.colorString = colorLabel.text
        vc.delegate = self
    }
}

และนั่นควรได้ผล แน่นอนว่านี่เป็นเพียงส่วนของโค้ด แต่ควรให้แนวคิดแก่คุณ สำหรับคำอธิบายยาว ๆ เกี่ยวกับรหัสนี้คุณสามารถไปที่รายการบล็อกของฉันได้ที่นี่:

Segues และผู้รับมอบสิทธิ์

หากคุณสนใจในสิ่งที่เกิดขึ้นภายใต้ประทุนกับตัวแทนฉันเขียนไว้ที่นี่:

ภายใต้ประทุนพร้อมผู้ร่วมประชุม


23
ขั้นตอนที่ 2 ไม่ควรมีการอ้างอิงที่อ่อนแอถึงผู้รับมอบสิทธิ์? ถ้าฉันถูกโปรดแก้ไข Btw คุณสามารถกำหนดค่าเป็นตัวเลือกได้ ที่จะรวดเร็วมากขึ้น ตัวแทนตัวแทนอ่อนแอ: FooTwoViewControllerDelegate? PS: ผู้รับมอบสิทธิ์ควรเป็นผู้ที่อ่อนแอในการรักษาวงกลมเด็กไม่ควรอ้างอิงถึงผู้ปกครองอย่าง
ชัดเจน

1
ในทางของฉันเมื่อคุณจะให้ผู้รับมอบสิทธิ์เป็นทางเลือกคุณจะแก้ไขข้อผิดพลาดในการแกะกล่อง delegate? .myVCDidFinish Becouse หากไม่ได้ตั้งค่า delegate cod จะไม่ดำเนินการในขณะนี้ :) ในเวอร์ชันของคุณจะพยายามดำเนินการและจะไม่สามารถแกะออกได้หากผู้รับมอบสิทธิ์เป็นศูนย์และคุณเป็น
Shial

4
คุณต้องประกาศโปรโตคอลเช่นนี้เพื่อให้การอ้างอิงที่อ่อนแอเป็นไปได้สำหรับโปรโตคอลที่มอบสิทธิ์ FooTwoViewControllerDelegate: class {}
codingrhythm

คุณช่วยกำหนดโดยแต่ละขั้นตอนที่ VC เป็นเช่น VC1 และ VC2 ฉันไม่แน่ใจจริงๆว่าจะวางไว้ที่ไหน
Cing

2
@Shial - อันที่จริงดูเหมือนจะซับซ้อนเล็กน้อย weakจำเป็นสำหรับคลาสเท่านั้นที่ไม่ใช่โครงสร้างและ enums หากผู้รับมอบสิทธิ์จะเป็นโครงสร้างหรือ enum คุณไม่จำเป็นต้องกังวลเกี่ยวกับการรักษารอบ อย่างไรก็ตามผู้รับมอบสิทธิ์เป็นคลาส (ซึ่งเป็นเรื่องจริงสำหรับหลาย ๆ กรณีเนื่องจากมักจะเป็น ViewController) คุณต้องweakแต่คุณต้องประกาศโปรโตคอลของคุณเป็นคลาส มีข้อมูลเพิ่มเติมที่นี่stackoverflow.com/a/34566876/296446
Robert

95

ผู้ได้รับมอบหมายเสมอฉันสับสนจนฉันตระหนักว่าเป็นตัวแทนเป็นเพียงระดับที่ไม่ทำงานบางอย่างสำหรับการเรียนอีก มันเหมือนกับมีคนอื่นมาทำงานสกปรกแทนคุณโดยที่คุณไม่อยากทำเอง

ฉันเขียนเรื่องราวเล็กน้อยเพื่อแสดงให้เห็นถึงสิ่งนี้ อ่านใน Playground ถ้าคุณต้องการ

กาลครั้งหนึ่ง...

// MARK: Background to the story

// A protocol is like a list of rules that need to be followed.
protocol OlderSiblingDelegate: class {
    // The following command (ie, method) must be obeyed by any 
    // underling (ie, delegate) of the older sibling.
    func getYourNiceOlderSiblingAGlassOfWater()
}

// MARK: Characters in the story

class BossyBigBrother {
    
    // I can make whichever little sibling is around at 
    // the time be my delegate (ie, slave)
    weak var delegate: OlderSiblingDelegate?
    
    func tellSomebodyToGetMeSomeWater() {
        // The delegate is optional because even though 
        // I'm thirsty, there might not be anyone nearby 
        // that I can boss around.
        delegate?.getYourNiceOlderSiblingAGlassOfWater()
    }
}

// Poor little sisters have to follow (or at least acknowledge) 
// their older sibling's rules (ie, protocol)
class PoorLittleSister: OlderSiblingDelegate {

    func getYourNiceOlderSiblingAGlassOfWater() {
        // Little sis follows the letter of the law (ie, protocol),
        // but no one said exactly how she had to respond.
        print("Go get it yourself!")
    }
}

// MARK: The Story

// Big bro is laying on the couch watching basketball on TV.
let bigBro = BossyBigBrother()

// He has a little sister named Sally.
let sally = PoorLittleSister()

// Sally walks into the room. How convenient! Now big bro 
// has someone there to boss around.
bigBro.delegate = sally

// So he tells her to get him some water.
bigBro.tellSomebodyToGetMeSomeWater()

// Unfortunately no one lived happily ever after...

// The end.

ในการตรวจสอบมีสามส่วนสำคัญในการสร้างและใช้รูปแบบผู้รับมอบสิทธิ์

  1. โปรโตคอลที่กำหนดสิ่งที่ผู้ปฏิบัติงานที่ต้องทำ
  2. ระดับเจ้านายที่มีตัวแปรตัวแทนซึ่งจะใช้เพื่อบอกระดับผู้ปฏิบัติงานว่าจะทำอย่างไร
  3. ระดับผู้ปฏิบัติงานที่ adopts โปรโตคอลและไม่สิ่งที่ถูกต้อง

ชีวิตจริง

เมื่อเปรียบเทียบกับเรื่องราว Bossy Big Brother ของเราข้างต้นผู้ได้รับมอบหมายมักใช้สำหรับการใช้งานจริงดังต่อไปนี้:

  1. การสื่อสาร : ชั้นเรียนหนึ่งต้องส่งข้อมูลบางอย่างไปยังชั้นเรียนอื่น
  2. การปรับแต่ง : คลาสหนึ่งต้องการอนุญาตให้คลาสอื่นปรับแต่งได้

ส่วนที่ดีคือคลาสเหล่านี้ไม่จำเป็นต้องรู้อะไรเกี่ยวกับกันและกันก่อนยกเว้นว่าคลาสที่ได้รับมอบหมายนั้นเป็นไปตามโปรโตคอลที่ต้องการ

ฉันขอแนะนำให้อ่านบทความสองบทความต่อไปนี้ พวกเขาช่วยให้ฉันเข้าใจผู้ได้รับมอบหมายให้ดียิ่งขึ้นกว่าเอกสารได้

อีกหนึ่งบันทึก

ผู้รับมอบสิทธิ์ที่อ้างอิงคลาสอื่น ๆ ที่พวกเขาไม่ได้เป็นเจ้าของควรใช้weakคีย์เวิร์ดเพื่อหลีกเลี่ยงรอบการอ้างอิงที่รัดกุม ดูคำตอบนี้สำหรับรายละเอียดเพิ่มเติม


3
ในที่สุดก็มีคนที่สามารถอธิบายโปรโตคอลและมอบหมายด้วยสามัญสำนึก! ขอบคุณมาก!
Engineeroholic

จะเกิดอะไรขึ้นเมื่อ Bossy Big Brother ไม่รู้ว่าเขาเป็นพี่ชาย (Generics)?
Marin

@ มารินฉันไม่แน่ใจจริงๆว่าฉันเข้าใจคำถามของคุณ รายการกฎ (โปรโตคอล) ไม่สนใจว่าใครเป็นผู้เรียกร้องให้ปฏิบัติตามกฎหรือใครปฏิบัติตามกฎ พวกเขาเป็นเพียงกฎ
Suragch

โดยทั่วไปฉันกำลังอ้างถึงคำถามของฉันง่ายกว่าเล็กน้อยที่นี่ stackoverflow.com/questions/41195203/…
มาริน

47

ฉันได้รับการแก้ไขเล็กน้อยในการโพสต์ของ @MakeAppPie

ก่อนอื่นเมื่อคุณสร้างโปรโตคอลตัวแทนควรเป็นไปตามโปรโตคอลคลาส เช่นในตัวอย่างด้านล่าง

protocol ProtocolDelegate: class {
    func myMethod(controller:ViewController, text:String)
}

ประการที่สองผู้แทนของคุณควรอ่อนแอเพื่อหลีกเลี่ยงการรักษาวงจร

class ViewController: UIViewController {
    weak var delegate: ProtocolDelegate?
}

สุดท้ายคุณปลอดภัยเพราะโปรโตคอลของคุณเป็นค่าที่ไม่บังคับ นั่นหมายความว่าข้อความ "ศูนย์" จะไม่ถูกส่งไปยังคุณสมบัตินี้ คล้ายกับคำสั่งเงื่อนไขrespondToselectorใน objC แต่ที่นี่คุณมีทุกอย่างในบรรทัดเดียว:

if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
    [self.delegate myMethod:self text:@"you Text"];
}

ด้านบนคุณมีตัวอย่าง obj-C และด้านล่างคุณมีตัวอย่าง Swift ว่ามีลักษณะอย่างไร

delegate?.myMethod(self, text:"your Text")

คุณปลอดภัยเพราะโปรโตคอลของคุณเป็นค่าที่เลือกได้ ..... เพราะคุณใช้การเชื่อมโยงที่เป็นทางเลือกdelegate?.myMethodจะไม่เกิดปัญหาเพราะถ้าเป็นผู้รับมอบสิทธิ์nilก็จะไม่มีอะไรเกิดขึ้น แต่ถ้าคุณทำผิดพลาดและเขียนdelegate!.myMethodคุณอาจมีปัญหาหากตัวแทนไม่ได้ตั้งค่าดังนั้นโดยทั่วไปวิธีสำหรับคุณที่จะปลอดภัย ...
น้ำผึ้ง

33

นี่คือสาระสำคัญที่ฉันรวบรวมไว้ ฉันสงสัยเหมือนกันและสิ่งนี้ช่วยปรับปรุงความเข้าใจของฉัน เปิดสิ่งนี้ในXcode Playgroundเพื่อดูว่าเกิดอะไรขึ้น

protocol YelpRequestDelegate {
    func getYelpData() -> AnyObject
    func processYelpData(data: NSData) -> NSData
}

class YelpAPI {
    var delegate: YelpRequestDelegate?

    func getData() {
        println("data being retrieved...")
        let data: AnyObject? = delegate?.getYelpData()
    }

    func processYelpData(data: NSData) {
        println("data being processed...")
        let data = delegate?.processYelpData(data)
    }
}

class Controller: YelpRequestDelegate {
    init() {
        var yelpAPI = YelpAPI()
        yelpAPI.delegate = self
        yelpAPI.getData()
    }
    func getYelpData() -> AnyObject {
        println("getYelpData called")
        return NSData()
    }
    func processYelpData(data: NSData) -> NSData {
        println("processYelpData called")
        return NSData()
    }
}

var controller = Controller()

รักสิ่งนี้. มีประโยชน์มาก
Aspen

@SeeMeCode สวัสดีเป็นตัวอย่างที่ดีประการแรก แต่ฉันยังคงมีปัญหา ฉันจะทำให้UIViewControllerชั้นเรียนของฉันเป็นไปตามตัวแทนที่เราทำไว้ได้อย่างไร พวกเขาต้องประกาศในไฟล์ที่รวดเร็วเพียงไฟล์เดียวหรือไม่ ความช่วยเหลือใด ๆ จะมีความหมายมาก
Faruk

@ ฟารักไม่นานแล้วที่ฉันโพสต์สิ่งนี้ แต่ฉันคิดว่าสิ่งที่คุณถามควรจะค่อนข้างง่าย (ถ้าฉันเข้าใจผิดฉันขอโทษ) เพียงเพิ่มผู้รับมอบสิทธิ์ใน UIViewController ของคุณหลังลำไส้ใหญ่ class ViewController : UIViewController NameOfDelegateดังนั้นสิ่งที่ต้องการ
SeeMeCode

@SeeMeCode ใช่คุณมีคำถามของฉันดี ฉันพยายามแนะนำของคุณครับ แต่เมื่อฉันสร้างชั้นผู้รับมอบสิทธิ์ในการตามคำตอบของคุณดังกล่าวข้างต้นก็ไม่ได้เกิดขึ้นในการa.swift b.swiftฉันไม่สามารถเข้าถึงชั้นเรียนใด ๆ นอกเหนือจากไฟล์ที่รวดเร็วของฉัน ความเหนียวใด ๆ ?
Faruk

สิ่งหนึ่งที่ฉันไม่เข้าใจคือเหตุใดฉันจึงควรสร้างอินสแตนซ์ใหม่ของ YelpApi เพื่อที่ฉันจะโทรหาตัวแทนของ YelpApi จะเกิดอะไรขึ้นถ้าอินสแตนซ์ที่กำลังทำงานอยู่แตกต่างจาก 'ใหม่' ที่ฉันเพิ่งสร้าง ... จะรู้ได้อย่างไรว่าผู้รับมอบสิทธิ์ใดเป็นของอินสแตนซ์ของ YelpApi
Marin

15

DELEGATES ใน SWIFT 2

ฉันกำลังอธิบายด้วยตัวอย่าง Delegate with two viewControllers ในกรณีนี้ SecondVC Object กำลังส่งข้อมูลกลับไปที่ View Controller ตัวแรก

คลาสที่มีการประกาศโปรโตคอล

protocol  getDataDelegate  {
    func getDataFromAnotherVC(temp: String)
}


import UIKit
class SecondVC: UIViewController {

    var delegateCustom : getDataDelegate?
    override func viewDidLoad() {
        super.viewDidLoad()
     }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    @IBAction func backToMainVC(sender: AnyObject) {
      //calling method defined in first View Controller with Object  
      self.delegateCustom?.getDataFromAnotherVC("I am sending data from second controller to first view controller.Its my first delegate example. I am done with custom delegates.")
        self.navigationController?.popViewControllerAnimated(true)
    }

}

ใน First ViewController Protocol สอดคล้องกันที่นี่:

class ViewController: UIViewController, getDataDelegate

นิยามวิธีโปรโตคอลใน First View Controller (ViewController)

func getDataFromAnotherVC(temp : String)
{
  // dataString from SecondVC
   lblForData.text = dataString
}

ระหว่างการกด SecondVC จาก First View Controller (ViewController)

let objectPush = SecondVC()
objectPush.delegateCustom = self
self.navigationController.pushViewController(objectPush, animated: true)

3 บรรทัดสุดท้ายของคุณช่วยให้ฉันเข้าใจสถานการณ์ของฉันและแก้ไขปัญหาของฉันได้ ขอบคุณผู้ชาย! :)
iHarshil

6

ชั้นหนึ่ง:

protocol NetworkServiceDelegate: class {

    func didCompleteRequest(result: String)
}


class NetworkService: NSObject {

    weak var delegate: NetworkServiceDelegate?

    func fetchDataFromURL(url : String) {
        delegate?.didCompleteRequest(url)
    }
}

ชั้นสอง:

class ViewController: UIViewController, NetworkServiceDelegate {

    let network = NetworkService()

    override func viewDidLoad() {
        super.viewDidLoad()
        network.delegate = self
        network.fetchDataFromURL("Success!")
    }



    func didCompleteRequest(result: String) {
        print(result)
    }


}

ในการรวบรวมโค้ดด้านบนจะแสดงข้อผิดพลาดโปรดType 'ViewController' does not conform to protocol 'NetworkServiceDelegate'แนะนำ เป็นวันที่ 6 ของฉันอย่างรวดเร็ว :)
Vaibhav Saran

4

ทีละขั้นตอนง่ายมาก (ทำงานและทดสอบได้ 100%)

ขั้นตอนที่ 1:สร้างวิธีการในตัวควบคุมมุมมองแรก

 func updateProcessStatus(isCompleted : Bool){
    if isCompleted{
        self.labelStatus.text = "Process is completed"
    }else{
        self.labelStatus.text = "Process is in progress"
    }
}

ขั้นตอนที่ 2:ตั้งค่าผู้รับมอบสิทธิ์ในขณะที่กดไปยังตัวควบคุมมุมมองที่สอง

@IBAction func buttonAction(_ sender: Any) {

    let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
    secondViewController.delegate = self
    self.navigationController?.pushViewController(secondViewController, animated: true)
}

ขั้นตอนที่ 3:ตั้งค่าผู้รับมอบสิทธิ์เช่น

คลาส ViewController: UIViewController, ProcessStatusDelegate {

ขั้นตอนที่ 4:สร้างโปรโตคอล

protocol ProcessStatusDelegate:NSObjectProtocol{
func updateProcessStatus(isCompleted : Bool)
}

ขั้นตอนที่ 5:รับตัวแปร

var delegate:ProcessStatusDelegate?

ขั้นตอนที่ 6:ในขณะที่กลับไปที่วิธีการมอบสิทธิ์การเรียกใช้ตัวควบคุมมุมมองก่อนหน้าดังนั้นตัวควบคุมมุมมองแรกจะแจ้งให้ทราบด้วยข้อมูล

@IBAction func buttonActionBack(_ sender: Any) {
    delegate?.updateProcessStatus(isCompleted: true)
    self.navigationController?.popViewController(animated: true)
}

@IBAction func buttonProgress(_ sender: Any) {
    delegate?.updateProcessStatus(isCompleted: false)
    self.navigationController?.popViewController(animated: true)

}

3

ตัวอย่างง่ายๆ:

protocol Work: class {
    func doSomething()
}

class Manager {
    weak var delegate: Work?
    func passAlong() {
        delegate?.doSomething()
    }
}

class Employee: Work {
    func doSomething() {
        print("Working on it")
    }
}

let manager = Manager()
let developer = Employee()
manager.delegate = developer
manager.passAlong() // PRINTS: Working on it

ทำไมคุณถึงใช้คำหลัก "class" ในคำอธิบายโปรโตคอล การใช้และไม่ใช้มันแตกต่างกันอย่างไร
Vlad

2
คีย์เวิร์ดของคลาสหมายความว่าเป็นโปรโตคอลคลาสเท่านั้น คุณสามารถ จำกัด การนำโปรโตคอลไปใช้กับประเภทคลาสไม่ใช่โครงสร้างหรือการแจงนับโดยการเพิ่มคีย์เวิร์ดคลาส ฉันอาจไม่ควรเพิ่มเพื่อหลีกเลี่ยงความสับสนใด ๆ แต่เนื่องจากคุณถามฉันจะเก็บไว้
Bobby

2

ผู้รับมอบสิทธิ์เป็นรูปแบบการออกแบบที่อนุญาตให้วัตถุหนึ่งส่งข้อความไปยังวัตถุอื่นเมื่อเกิดเหตุการณ์เฉพาะ ลองนึกภาพวัตถุ A เรียกวัตถุ B เพื่อดำเนินการ เมื่อการดำเนินการเสร็จสิ้นวัตถุ A ควรรู้ว่า B ทำงานเสร็จแล้วและดำเนินการตามความจำเป็นสิ่งนี้สามารถทำได้ด้วยความช่วยเหลือของผู้ได้รับมอบหมาย! นี่คือบทช่วยสอนการใช้งานตัวแทนทีละขั้นตอนใน swift 3

ลิงค์บทช่วยสอน


0

โซลูชันข้างต้นดูเหมือนจะเชื่อมโยงกันเล็กน้อยและในขณะเดียวกันก็หลีกเลี่ยงการนำโปรโตคอลเดียวกันมาใช้ซ้ำในตัวควบคุมอื่น ๆ นั่นเป็นเหตุผลที่ฉันมาพร้อมกับโซลูชันที่พิมพ์ได้ชัดเจนยิ่งขึ้นโดยใช้การลบประเภททั่วไป

@noreturn public func notImplemented(){
    fatalError("not implemented yet")
}


public protocol DataChangedProtocol: class{
    typealias DataType

    func onChange(t:DataType)
}

class AbstractDataChangedWrapper<DataType> : DataChangedProtocol{

    func onChange(t: DataType) {
        notImplemented()
    }
}


class AnyDataChangedWrapper<T: DataChangedProtocol> : AbstractDataChangedWrapper<T.DataType>{

    var base: T

    init(_ base: T ){
        self.base = base
    }

    override func onChange(t: T.DataType) {
        base.onChange(t)
    }
}


class AnyDataChangedProtocol<DataType> : DataChangedProtocol{

    var base: AbstractDataChangedWrapper<DataType>

    init<S: DataChangedProtocol where S.DataType == DataType>(_ s: S){
        self.base = AnyDataChangedWrapper(s)
    }

    func onChange(t: DataType) {
        base.onChange(t)
    }
}



class Source : DataChangedProtocol {
    func onChange(data: String) {
        print( "got new value \(data)" )
    }
}


class Target {
    var delegate: AnyDataChangedProtocol<String>?

    func reportChange(data:String ){
        delegate?.onChange(data)
    }
}


var source = Source()
var target = Target()

target.delegate = AnyDataChangedProtocol(source)
target.reportChange("newValue")    

เอาต์พุต : มีค่าใหม่ newValue


ฉันสนใจที่จะเรียนรู้เพิ่มเติมเกี่ยวกับเรื่องนี้ คุณสามารถอธิบายเพิ่มเติมเกี่ยวกับคำศัพท์ที่คุณใช้คู่กัน, "หลีกเลี่ยงการใช้โปรโตคอลเดียวกันซ้ำ", "การลบข้อมูลประเภททั่วไป" เหตุใดการทำนามธรรมจึงสำคัญเช่นนี้ ควรทำสิ่งนี้เสมอหรือไม่?
Suragch

0

ใน Swift 4.0

สร้างผู้รับมอบสิทธิ์ในชั้นเรียนที่ต้องการส่งข้อมูลบางอย่างหรือมอบฟังก์ชันการทำงานบางอย่างให้กับชั้นเรียนอื่น

ชอบ

protocol GetGameStatus {
    var score: score { get }
    func getPlayerDetails()
}

หลังจากนั้นในชั้นเรียนที่จะยืนยันกับผู้รับมอบสิทธิ์นี้

class SnakesAndLadders: GetGameStatus {
    func getPlayerDetails() {

 }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.