如何在swift中实现监听器模式

use*_*077 5 design-patterns ios swift

我是从 java 搬来的 swift 新手。设计模式的一些实现让我感到困惑。

例如,我在java代码中有presudo模式观察者(回调)(下面有示例)。即 UI 将自己的侦听器传递给 Manager 类并侦听回调 isConnected 和 isDisconnected。如果执行回调,UI 类会显示某些消息“isConnected”或“isDisconnected”

    public class UI{
        private Manager mManager;
        void createManager(){
            mManager = new Manager(mManagerLister);
        }
        public void showMessage(String aMsg){
            print(aMsg)
        }
        private final IManagerListener mManagerLister = new IManagerListener{
            void isConnected(){
                this.showMessage("isConnected") 
            }
            void isDisconnected(){
                this.showMessage("isConnected")
            }
        }
    }

    public class Manager{
        interface IManagerListener{
            void isConnected();
            void isDisconnected();
        }
        private final mListener; 
        public Manager(IManagerListener aListener){
            mListener = aListener;
        }
    }
Run Code Online (Sandbox Code Playgroud)

如何正确地将这个java代码移植到swift代码?我尝试移植,但显示错误消息Value of type 'UI' has no member 'showMessage'

  public class UI{
    var manager: Manager?
    var managerListener: IManagerListener?
    func createManager(){
        managerListener = ManagerListenerImp(self)  
        manager = Manager(managerListener)
    }
    public func showMessage(msg: String){
        print(msg)
    }
    class ManagerListenerImp: IManagerListener{
        weak var parent: UI 
        init(parent : UI ){
            self.parent = parent
        }
        func isConnected(){
            parent.showMessage("isConnected") 
            // Value of type 'UI' has no member 'showMessage'
            }
        ..........
    } 
} 
Run Code Online (Sandbox Code Playgroud)

也许存在更优雅的使用回调的方法,而我的方法不正确?

San*_*ari 3

有多种方法可以实现它。

  1. 委托模式(使用Java中的接口只不过是协议)
  2. 使用块/闭包
  3. 使用 KVO

因为您已经使用过接口,所以我在下面详细阐述委托模式。

修改您的代码如下

声明一个协议

@objc protocol ManagerListenerImp {
    func isConnected()
}
Run Code Online (Sandbox Code Playgroud)

在Manager类中声明一个变量

class Manager {
    weak var delegate : ManagerListenerImp? = nil
}
Run Code Online (Sandbox Code Playgroud)

ManagerListenerImp在您的 UI 类中确认

extension UI : ManagerListenerImp {
    func isConnected () {
        //your isConnected implementation here
    }
}
Run Code Online (Sandbox Code Playgroud)

传递 UI 实例(swift 中的 self 和 JAVA 中的 this 到管理器类)

func createManager(){
    manager = Manager()
    manager?.delegate = self
}
Run Code Online (Sandbox Code Playgroud)

最后,每当你想isConnectedManager课堂上触发时,只需说

self.delegate?.isConnected()
Run Code Online (Sandbox Code Playgroud)

在您的经理班级中

希望能帮助到你