2016-05-12 55 views
0

我有一個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. 我應該在這裏使用單例模式嗎?

回答

1
  1. 我在代碼中看不到保留循環。如果你怕有些對象不破壞時的預期,您可以登錄其釋放的檢查:

    deinit { 
        print("deinit of \(self)") 
    } 
    
  2. 同意,那你更需要引入一些模型級的實體,爲國家照顧,而不是有它的控制器圖層。如果你不打算用單元測試來涵蓋相關的邏輯,Singleton是可以的。

EDITED

你可以存儲在共享應用程序委託對象。

不確定我完全理解你的應用程序對象模型。我認爲應該在所有應用程序中共享狀態,所以最好將一些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) 
      } 
     } 
    } 
+0

謝謝。你能否在這個特定的用例中提出一個單例的替代方案? – Zaxter

+0

太棒了!感謝您花時間寫這篇文章!非常感激。 – Zaxter