programing

딜러들이 신속하게?

lovejava 2023. 5. 29. 09:05

딜러들이 신속하게?

수 어대자만수들까있니습를표게떻?까,▁a?NSUserNotificationCenterDelegate 속하게신?

다음은 두 뷰 컨트롤러 간의 딜러에 대한 약간의 도움말입니다.

1단계: 데이터를 제거하거나 전송할 프로토콜을 UIViewController에서 만듭니다.

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

2단계: 전송 클래스의 딜러를 선언합니다(예: UIView 컨트롤러).

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단계: prepareForSegue에서 딜러를 설정합니다.

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
    }
}

그리고 그것은 효과가 있을 것입니다.물론 이것은 코드 조각에 불과하지만, 아이디어를 제공해야 합니다.이 코드에 대한 자세한 설명을 보려면 블로그 항목으로 이동하십시오.

세그와 대표단

만약 당신이 대표와 함께 후드 아래에서 무슨 일이 일어나고 있는지에 관심이 있다면, 저는 여기에 썼습니다:

대표단을 거느리고.

딜러는 항상 저를 혼란스럽게 만들었지만, 제가 딜러는 다른 클래스를 위해 일을 하는 클래스일 뿐이라는 을 알게 되었습니다.당신이 하고 싶지 않은 더러운 일을 당신을 위해 다른 누군가가 그곳에 있는 것과 같습니다.

저는 이것을 설명하기 위해 작은 이야기를 썼습니다.원한다면 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. 의정서를 채택하고 필요한 일을 하는 노동자 계급

실생활

위의 'Bossy Big Brother' 사례와 비교하여 딜러는 다음과 같은 실용적인 용도로 자주 사용됩니다.

  1. 통신: 한 클래스에서 다른 클래스로 일부 정보를 전송해야 합니다.
  2. 사용자 지정: 한 클래스에서 다른 클래스가 사용자 지정할 수 있도록 허용합니다.

중요한 부분은 이러한 클래스가 사전에 서로에 대해 아무것도 알 필요가 없다는 것입니다. 단, 위임 클래스는 필수 프로토콜을 준수합니다.

저는 다음 두 개의 기사를 읽는 것을 강력히 추천합니다.문서보다 딜러들을 더 잘 이해할 수 있도록 도와주었습니다.

노트 하나 더

하고 있지 하는 딜러는 자신소않다클래딜을 .weak키워드를 지정하여 강한 참조 주기를 방지합니다.자세한 내용은 이 답변을 참조하십시오.

그것은 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;

@MakeAppPie를 게시하기 위해 몇 가지 수정 사항이 있습니다.

먼저 위임 프로토콜을 만들 때 클래스 프로토콜을 준수해야 합니다.아래의 예와 같습니다.

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

둘째, 대리인은 주기 유지를 피하기 위해 약해야 합니다.

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

마지막으로, 프로토콜은 선택적인 값이므로 안전합니다.가 이합니다.", "nil" 메시이속전송로으않되습지니다즉성가지▁that않습니다,▁will지▁"즉되송전메▁"▁messagen▁be▁its▁to.조건문과 유사합니다.respondToselector이 한 됩니다. objC에서는 objC로 됩니다.

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

위에는 obj-C 예제가 있고 아래에는 Swift 예제가 있습니다.

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

여기 제가 정리한 요지가 있습니다.저도 마찬가지로 궁금했고 이것이 제 이해력을 높이는 데 도움이 되었습니다.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()

스위프트 2의 딜러

두 개의 뷰 컨트롤러가 있는 Delegate의 예를 들어 설명합니다.이 경우 두 번째 VC 개체는 첫 번째 View 컨트롤러로 데이터를 다시 보냅니다.

프로토콜 선언이 있는 클래스

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(temp: "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 View Controller Protocol에서 준수는 다음과 같이 수행됩니다.

class ViewController: UIViewController, getDataDelegate

First View Controller(View Controller)의 프로토콜 방법 정의

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

First View 컨트롤러(View Controller)에서 Second VC를 누르는 동안

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

일등석:

protocol NetworkServiceDelegate: class {
        
    func didCompleteRequest(result: String)
}


class NetworkService: NSObject {

    weak var delegate: NetworkServiceDelegate?
    
    func fetchDataFromURL(url : String) {
        delegate?.didCompleteRequest(result: url)
    }
}

두 번째 클래스:

class ViewController: UIViewController, NetworkServiceDelegate {
    
    let network = NetworkService()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        network.delegate = self
        network.fetchDataFromURL(url: "Success!")
    }

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


}

단계적으로 매우 간단함(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단계: 딜러를 다음과 같이 설정

클래스 뷰 컨트롤러:UIView 컨트롤러, 프로세스 상태 딜러 {

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)

}

간단한 예:

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

대리인은 특정 이벤트가 발생할 때 한 개체가 다른 개체로 메시지를 보낼 수 있도록 하는 설계 패턴입니다.객체 A가 객체 B를 호출하여 동작을 수행한다고 상상해 보십시오.작업이 완료되면 개체 A가 B가 작업을 완료했음을 알고 필요한 조치를 취해야 합니다. 딜러의 도움을 받아 이 작업을 수행할 수 있습니다!다음은 딜러들을 단계별로 swift 3으로 구현하는 튜토리얼입니다.

자습서 링크

실생활 대리인 시나리오는 다음과 같습니다.
고유한 UITextField 및 UITextField 딜러를 만듭니다.

// THE MYSTERIOUS UITEXTFIELD

protocol UITextFieldDelegate {
    func textFieldDidChange(_ textField: UITextField) -> Void
}

class UITextField {
    var delegate: UITextFieldDelegate?
    private var mText: String?
    var text: String? {
        get {
            return mText
        }
    }
    
    init(text: String) {
        
    }
    
    init() {
        
    }
    
    func setText(_ text: String) {
        mText = text
        delegate?.textFieldDidChange(self)
    }

}
// HERE IS MY APP

class Main {
    
    let textfield = UITextField()
    
    func viewDidLoad() {
        print("viewDidLoad")
        textfield.delegate = self
        textfield.setText("Hello")
    }
    
}

extension Main: UITextFieldDelegate {
    
    func textFieldDidChange(_ textField: UITextField) {
        print(textField.text ?? "No string")
    }
    
}

let main = Main()
main.viewDidLoad()

딜러의 단순 코드 예:

//MARK: - Protocol ShowResult
protocol ShowResult: AnyObject {
       func show(value: Int) 
  }

//MARK: - MyOperation Class
class MyOperation {
weak var delegate: ShowResult?

func sum(fNumber: Int, sNumber: Int) {
    delegate?.show(value: fNumber + sNumber)
  }
}

//MARK: - ViewController Class
class ViewController: UIViewController,ShowResult {
var myOperation: MyOperation?

override func viewDidLoad() {
    super.viewDidLoad()
    loadMyOperation()
    myOperation?.delegate = self
    myOperation?.sum(fNumber: 100, sNumber: 20)
 }

private func loadMyOperation() {
    if myOperation == nil {
        myOperation = MyOperation()
     }
 }

func show(value: Int) {
    print("value: \(value)")
   }
}

위의 솔루션은 약간 결합된 것처럼 보였고 동시에 다른 컨트롤러에서도 동일한 프로토콜을 재사용하는 것을 피했습니다. 따라서 일반 유형 삭제를 사용하여 보다 강력한 유형의 솔루션을 개발했습니다.

@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

인스위프트 4.0

일부 데이터를 전송하거나 일부 기능을 다른 클래스에 제공해야 하는 클래스의 대리자 만들기

맘에 들다

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

수업이 끝난 후 이 딜러에게 확인합니다.

class SnakesAndLadders: GetGameStatus {
    func getPlayerDetails() {

 }
}

인스위프트 5

저는 초보자입니다, 이것이 실제 시나리오에서 가장 쉽게 이해할 수 있는 방법이라고 생각합니다.

참고: 모든 즉흥 연주가 가장 좋습니다.

protocol APIService {
   func onSuccessResponse() -> AnyObject
   func onFailureResponse() -> AnyObject
}

class APIHelper{

var delegate : APIService?

func postUsersDataAPI() {
    //assuming API communication is success
    if(success){
       let _: AnyObject? = delegate?.onSuccessResponse()
    }else if(failure){
       let _: AnyObject? = delegate?.onFailureResponse()
  }
 }

func getAllUsersAPI() {
    //assuming API communication is success
   if(success){
       let _: AnyObject? = delegate?.onSuccessResponse()
    }else if(failure){
       let _: AnyObject? = delegate?.onFailureResponse()
  }
 }
}


class ViewController:UIViewController,APIService {

func onSuccessResponse() -> AnyObject {
    print("onSuccessResponse") as AnyObject
}

func onFailureResponse() -> AnyObject {
    print("onFailureResponse") as AnyObject
}

@IBAction func clickBtnToPostUserData(_ sender: Any) { 
    let apiHelper = APIHelper()
    apiHelper.delegate = self
    apiHelper.postAPI()
}

언급URL : https://stackoverflow.com/questions/24099230/delegates-in-swift