Patr贸n de observador en Swift

隆Buenos d铆as! Este art铆culo se centrar谩 en el patr贸n Observer. Todos los involucrados en el desarrollo de iOS probablemente se hayan encontrado con herramientas que se basan en este patr贸n. Por ejemplo, NotificationCenter, KVO o el gran y poderoso RxSwift, que es muy popular ahora. En este art铆culo, usar茅 un ejemplo simple para analizar c贸mo funciona este patr贸n. 隆No juren, perfeccionistas! Este art铆culo trata exclusivamente sobre el patr贸n Observer, por lo que, para mayor claridad, algunos de los principios del estilo de c贸digo tuvieron que descuidarse. 





Ejemplo de la vida real

, Youtube . Subscribe ! . 





. , , - .  .





.









Storyboard, Swift.





Main.storyboard





: " ", " ", , . 4xUILabel, 1XUIButton, 1xUISwitch. UILabel, UIButton.





.





. Option ViewController. . ViewController. .





, .





, Observer.





protocol Subscriber : AnyObject {
    func update(subject : Bloger )
}
      
      



Bloger. , . .





class Bloger {
    var counter : Int = 0
    var lastVideo = ""    
}
      
      



, . Subscriber, retain cycle , , . , , Subscriber :





//Fix retain cycle
struct WeakSubscriber {
    weak var value : Subscriber?
}

class Bloger {
  
private lazy var subscribers : [WeakSubscriber] = [] //    
}
      
      



, .





func subscribe(_ subscriber: Subscriber) {
        print("subscribed")
        subscribers.append(WeakSubscriber(value: subscriber))
    }
      
      



, . , , . , .





func unsubscribe(_ subscriber: Subscriber) {
        subscribers.removeAll(where: { $0.value === subscriber })
        print("unsubscribed")
    }
      
      



:





func notify() {
        subscribers.forEach { $0.value?.update(subject: self)
        }
    }
      
      



, . .





func releaseVideo() {
        counter += 1
        lastVideo = "video" + "\(counter)"
        notify() //Notify subscribers
  			print("released!")
    }
      
      



:





//Fix retain cycle
struct WeakSubscriber {
    weak var value : Subscriber?
}

class Bloger {
    
    private lazy var subscribers : [WeakSubscriber] = [] //    
    
    var counter : Int = 0
    var lastVideo = ""
    
    func subscribe(_ subscriber: Subscriber) {
        print("subscribed")
        subscribers.append(WeakSubscriber(value: subscriber))
    }
    
    func unsubscribe(_ subscriber: Subscriber) {
        subscribers.removeAll(where: { $0.value === subscriber })
        print("unsubscribed")
    }
    
    func notify() {
        subscribers.forEach { $0.value?.update(subject: self)
        }
    }
    
    func releaseVideo() {
        counter += 1
        lastVideo = "video" + "\(counter)"
        notify()
        print("released!")
    }
    
}
      
      



-. Subscriber ViewController.





Label , .





func update(subject: Bloger) {
        subscriberInfoLabel.text = subject.lastVideo
    }
      
      



Bloger() .





let bloger = Bloger()
      
      



ViewDidLoad .





bloger.subscribe(self)
      
      



, . :





 @IBAction func publishButton(_ sender: Any) {
        bloger.releaseVideo()
    }
 @IBAction func subscribeToggle(_ sender: Any) {
        if (sender as AnyObject).isOn {
            bloger.subscribe(self)
        } else {
            bloger.unsubscribe(self)
        }
    }
      
      



:





import UIKit

class ViewController: UIViewController, Subscriber {
    
    @IBOutlet weak var subscriberInfoLabel: UILabel!
    
    var bloger = Bloger()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        bloger.subscribe(self)
    }

    @IBAction func publishButton(_ sender: Any) {
        bloger.releaseVideo()
    }
    @IBAction func subscribeToggle(_ sender: Any) {
        if (sender as AnyObject).isOn {
            bloger.subscribe(self)
        } else {
            bloger.unsubscribe(self)
        }
    }
    
    func update(subject: Bloger) {
        subscriberInfoLabel.text = subject.lastVideo
    }
}

//MARK:- Protocols
protocol Subscriber : UIViewController {
    func update(subject : Bloger )
}

//Fix retain cycle
sruct WeakSubscriber { 
    weak var value : Subscriber?
}

class Bloger {
    
    private lazy var subscribers : [WeakSubscriber] = [] //   
    
    var counter : Int = 0
    var lastVideo = ""
    
    func subscribe(_ subscriber: Subscriber) {
        print("subscribed")
        subscribers.append(WeakSubscriber(value: subscriber))
    }
    
    func unsubscribe(_ subscriber: Subscriber) {
        subscribers.removeAll(where: { $0.value === subscriber })
        print("unsubscribed")
    }
    
    func notify() {
        subscribers.forEach { $0.value?.update(subject: self)
        }
    }
    
    func releaseVideo() {
        counter += 1
        lastVideo = "video" + "\(counter)"
        notify()
        print("released!")
    }
    
}
      
      



, !





, Observer, !












All Articles