NotificationCenter.default.addObserver(self,
    selector: #selector(nowPlayingItemChanged),
    name: .MPMusicPlayerControllerNowPlayingItemDidChange,
    object: nil)



@objc func nowPlayingItemChanged (_ n:Notification) {
    self.updateNowPlayingItem()
    // Itd.
}



let ob = NotificationCenter.default.addObserver(
    forName: .MPMusicPlayerControllerNowPlayingItemDidChange,
    object: nil, queue: nil) { _ in
        self.updateNowPlayingItem()
        // Itd.
    }



let ob = NotificationCenter.default.addObserver(
    forName: .MPMusicPlayerControllerNowPlayingItemDidChange,
    object: nil, queue: nil) { _ in
        self.updateNowPlayingItem()
        // Itd.
    }
self.observers.insert(ob as! NSObject)



for ob in self.observers {
    NotificationCenter.default.removeObserver(ob)
}
self.observers.removeAll()



class ViewController : UIViewController, UINavigationControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.delegate = self
    }
    func navigationControllerSupportedInterfaceOrientations(
        _ nav: UINavigationController) -> UIInterfaceOrientationMask {
            return .portrait
    }
}



protocol ColorPickerDelegate : class {
    // color == nil, po anulowaniu operacji
    func colorPicker(_ picker:ColorPickerController,
        didSetColorNamed theName:String?,
        to theColor:UIColor?)
}
class ColorPickerController : UIViewController {
    weak var delegate: ColorPickerDelegate?
    // …
}



extension SettingsController : ColorPickerDelegate {
    func showColorPicker() {
        let colorName = // …
        let c = // …
        let cpc = ColorPickerController(colorName:colorName, color:c)
        cpc.delegate = self
        self.present(cpc, animated: true)
    }
    func colorPicker(_ picker:ColorPickerController,
        didSetColorNamed theName:String?,
        to theColor:UIColor?) {
            // …
    }
}



@IBAction func dismissColorPicker(_ sender : Any?) { // Użytkownik nacisnął przycisk Gotowe.
    let c : UIColor? = self.color
    self.delegate?.colorPicker(self, didSetColorNamed: self.colorName, to: c)
}



extension NewGameController: UIPickerViewDataSource, UIPickerViewDelegate {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    func pickerView(_ pickerView: UIPickerView,
        numberOfRowsInComponent component: Int) -> Int {
            return 9
    }
    func pickerView(_ pickerView: UIPickerView,
        titleForRow row: Int, forComponent component: Int) -> String? {
            return "\(row+1) krok" + ( row > 0 ? "ów" : "")
    }
}



@IBAction func buttonPressed(_ sender: Any) {
    let alert = UIAlertController(
        title: "Cześć!", message: "Nacisnąłeś mnie!", preferredStyle: .alert)
    alert.addAction(
        UIAlertAction(title: "OK", style: .cancel))
    self.present(alert, animated: true)
}



override func awakeFromNib() {
    super.awakeFromNib()
    class Dummy {
        @objc func buttonPressed(_:Any) {}
    }
    self.addTarget(nil, // Celem jest nil.
        action: #selector(Dummy.buttonPressed),
        for: .touchUpInside)
}



class MyClass2 {
    var obs = Set<NSKeyValueObservation>() // 1.
    func registerWith(_ mc:MyClass1) {
        let opts : NSKeyValueObservingOptions = [.old, .new]
        let ob = mc.observe(\.value, options: opts) { obj, change in // 2.
            // Obserwowanym obiektem jest obj.
            // Obiekt change to egzemplarz NSKeyValueObservedChange.
            if let oldValue = change.oldValue {
                print("Poprzednia wartość to \(oldValue).")
            }
            if let newValue = change.newValue {
                print("Nowa wartość to \(newValue).")
            }
        }
        obs.insert(ob) // 3.
    }
}



func delay(_ delay:Double, closure:@escaping () -> ()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}



override func tableView(_ tableView: UITableView,
    didSelectRowAt indexPath: IndexPath) {
        let t = TracksViewController(
            mediaItemCollection: self.albums[indexPath.row])
        self.navigationController?.pushViewController(t, animated: true)
}



override func setSelected(_ selected: Bool, animated: Bool) {
    if selected {
        self.activityIndicator.startAnimating()
    } else {
        self.activityIndicator.stopAnimating()
    }
    super.setSelected(selected, animated: animated)
}



override func tableView(_ tableView: UITableView,
    didSelectRowAt indexPath: IndexPath) {
        delay(0.1) {
            let t = TracksViewController(
                mediaItemCollection: self.albums[indexPath.row])
            self.navigationController?.pushViewController(t, animated: true)
        }
}



