代码之家  ›  专栏  ›  技术社区  ›  user2930077

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

  •  4
  • user2930077  · 技术社区  · 6 年前

    我是刚从爪哇搬到斯威夫特的。一些设计模式的实现让我困惑。

    例如,我有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;
            }
        }
    

    如何将此java代码正确地移植到swift代码?我尝试移植但出现错误消息 “UI”类型的值没有成员“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'
                }
            ..........
        } 
    } 
    

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

    2 回复  |  直到 6 年前
        1
  •  2
  •   Sandeep Bhandari    6 年前

    有多种方法可以实现这一目标。

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

    因为您使用了接口,所以我将在下面详细介绍委托模式。

    按以下方式修改代码

    声明协议

    @objc protocol ManagerListenerImp {
        func isConnected()
    }
    

    在Manager类中声明变量

    class Manager {
        weak var delegate : ManagerListenerImp? = nil
    }
    

    确认至 ManagerListenerImp 在UI类中

    extension UI : ManagerListenerImp {
        func isConnected () {
            //your isConnected implementation here
        }
    }
    

    将UI实例(swift中的self和JAVA中的this传递给manager类)

    func createManager(){
        manager = Manager()
        manager?.delegate = self
    }
    

    最后,只要你想触发 isConnected 从…起 Manager 课堂简单地说

    self.delegate?.isConnected()
    

    在你的经理课上

    希望有帮助

        2
  •  1
  •   Arjo Nagelhout    3 年前

    我对哪个类引用哪个类有点困惑,但在下面的示例中,这应该不会太难改变。

    您可能正在寻找观察者模式。这可以使多个对象侦听相同的更改:

    1、ManagerStateListener协议

    由应对管理器状态更改作出反应的任何类实现的协议

    protocol ManagerStateListener: AnyObject {
        func stateChanged(to state: Manager.State)
    }
    

    2、经理类

    Manager类包含:

    1. 其状态
    2. 包含侦听器的列表
    3. 用于添加、删除和调用侦听器的方法
    4. 实现ManagerStateListener协议的示例类
    
    class Manager {
        
        /// The possible states of the Manager
        enum State {
            case one
            case two
            case three
        }
        
        /// The variable that stores the current state of the manager
        private var _currentState: State = .one
        var currentState: State {
            get {
                return _currentState
            }
            set {
                _currentState = newValue
                
                /// Calls the function that will alert all listeners
                /// that the state has changed
                invoke()
            }
        }
        
        /// The list with all listeners
        var listeners: [ManagerStateListener] = []
        
        /// A specific listener that gets initialised here
        let someListener = SomeListener()
        
        init() {
            addListener(someListener) /// Add the listener to the list
        }
        
        /// Method that invokes the stateChanged method on all listeners
        func invoke() {
            for listener in listeners {
                listener.stateChanged(to: currentState)
            }
        }
        
        /// Method for adding a listener to the list of listeners
        func addListener(_ listener: ManagerStateListener) {
            listeners.append(listener)
        }
        
        /// Method for removing a specific listener from the list of listeners
        func removeListener(_ listener: ManagerStateListener) {
            if let index = listeners.firstIndex(where: { $0 === listener }) {
                listeners.remove(at: index)
            }
        }
    }
    

    3、SomeListener类

    实现ManagerStateListener协议的示例侦听器,由Manager类持有

    class SomeListener : ManagerStateListener {
        
        func stateChanged(to state: Manager.State) {
            /// Do something based on the newly received state
            switch state {
                case .one:
                    print("State changed to one")
                case .two:
                    print("State changed to two")
                case .three:
                    print("State changed to three")
            }
        }
    }
    

    我希望这能有所帮助。