我这里有很强的参考周期吗



我有一个BaseViewController,它被我的应用程序中的所有其他视图控制器子类化。

我有一些状态变量,它们必须在所有视图控制器中保持一致,所以我计划编写代码,以便在BaseViewController中来回传递这些状态变量一次。为此,我提供了一个用于前向传递的辅助函数pushStatefulViewControllerWithIdentifier(),并使用StatePassBackDelegate用于后向传递。

import UIKit
class BaseViewController: UIViewController, StatePassBackDelegate {
    class State {
        var connected = false
        var loggedIn = false
    }

    var state = State()
    weak var delegate: StatePassBackDelegate? = nil

    // MARK: Lifecycle
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        if self.isMovingFromParentViewController() == true {
            delegate?.passBackState(state)
        }
    }

    // MARK: StatePassBackDelegate functions
    func passBackState(state: AnyObject) {
        self.state = state as! State
    }

    // MARK: Helpers
    final func pushStatefulViewControllerWithIdentifier(identifier: String) {
        let vc = storyboard?.instantiateViewControllerWithIdentifier(identifier) as! BaseViewController
        vc.state = state
        vc.delegate = self
        navigationController!.pushViewController(vc, animated: true)
    }
}

protocol StatePassBackDelegate: class {
    func passBackState(state: AnyObject)
}
  1. 我这里有强参考周期吗
  2. 我应该在这里使用singleton模式吗
  1. 我在您的代码中看不到保留循环。如果你担心某个对象没有在预期的时间内销毁,你可以记录它的释放以检查:

    deinit {
        print("deinit of (self)")
    }
    
  2. 同意,您需要引入一些模型级别的实体来进行状态关怀,而不是将其放在控制器层。如果您不打算用单元测试来覆盖相关的逻辑,那么Singleton是可以的。

已编辑

您可以将共享对象存储在应用程序委派中。

不确定我是否完全理解您的应用程序对象模型。我假设状态应该在所有应用程序中共享,所以最好将一些SystemStateMachine注入所有感兴趣的组件中。希望能有所帮助:

    @UIApplicationMain
    class MyAppDelegate: UIResponder, UIApplicationDelegate {
        var controllersFactory: IViewControllersFactory! = nil
        func applicationDidFinishLaunching(application: UIApplication) {
            let storyboard = UIStoryboard(name:NSBundle.mainBundle().infoDictionary!["UIMainStoryboardFile"] as! String , bundle: NSBundle.mainBundle())
            controllersFactory = ViewControllersFactory(storyboard: storyboard, stateMachine: SystemStateMachine())
        }
    }
    struct SystemState : OptionSetType {
        let rawValue: Int
        static let None   = SystemState(rawValue: 0)
        static let Connected = SystemState(rawValue: 1 << 0)
        static let LoggedIn  = SystemState(rawValue: 1 << 1)
    }
    protocol ISystemStateMachine {
        var currentState: SystemState { get set }
    }
    class SystemStateMachine: ISystemStateMachine {
        var currentState: SystemState = .None
    }
    protocol IViewControllersFactory {
        func instantiateViewController(identifier: String) -> BaseViewController?
    }
    class ViewControllersFactory: IViewControllersFactory {
        let _storyboard: UIStoryboard
        let _stateMachine: ISystemStateMachine
        init(storyboard: UIStoryboard, stateMachine: ISystemStateMachine) {
            _storyboard = storyboard
            _stateMachine = stateMachine
        }
        func instantiateViewController(identifier: String) -> BaseViewController? {
            if let vc = _storyboard.instantiateViewControllerWithIdentifier(identifier) as? BaseViewController {
                vc.stateMachine = _stateMachine
                return vc
            }
            return nil
        }
    }
    class BaseViewController: UIViewController {
        var stateMachine: ISystemStateMachine!
        // MARK: Lifecycle
        func somethingWorthHappen() {
            //switch state
            stateMachine.currentState.insert(.Connected)
        }
        func somethingWorth2Happen() {
            //switch state
            stateMachine.currentState.insert(.LoggedIn)
            guard let appDelegate = UIApplication.sharedApplication().delegate as? MyAppDelegate else {
                //log an error
                return
            }
            if let vc = appDelegate.controllersFactory.instantiateViewController("myViewController") {
                navigationController!.pushViewController(vc, animated: true)
            }
        }
    }

最新更新