重构开关语句



有没有办法重构这个函数,让我尽可能少地重复我自己?

我有四个视图控制器,每个控制器都有一个变量eventData这是一个自定义对象。

我想过eventData成为全局变量。这样做有什么缺点吗?

这是我现在使用的代码:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    navigationItem.title = nil
    let segues = UIStoryboardSegue.Segue.self
    switch segue.identifier! {
    case segues.EventOverviewToGuestList.rawValue:
        let destinationVC = segue.destinationViewController as! GuestListVC
        destinationVC.eventData = eventData

    case segues.EventOverviewToAnalytics.rawValue:
        let destinationVC = segue.destinationViewController as! AnalyticsVC
        destinationVC.eventData = eventData

    case segues.EventOverviewToMessaging.rawValue:
        let destinationVC = segue.destinationViewController as! MessagingVC
        destinationVC.eventData = eventData

    case segues.EventOverviewToInformation.rawValue:
        let destinationVC = segue.destinationViewController as! InformationVC
        destinationVC.eventData = eventData
    default: break
    }
}

segues是一个enum

extension UIStoryboardSegue {
    enum Segue : String
    {
        case EventListToEventOverview
        case EventOverviewToGuestList
        case EventOverviewToAnalytics
        case EventOverviewToMessaging
        case EventOverviewToInformation
    }
}

是的,您可以有一个具有此 eventData 成员的基类。比方说——

class BaseViewController : UIViewController{
    var eventData : SomeCustomClass?
}

并从中派生所有需要事件数据的视图控制器。

class InformationVC : BaseViewController{
}
class AnalyticsVC : BaseViewController{
}
class GuestListVC:BaseViewController{
}

现在,您的案例可以合并:

switch segue.identifier! {
  case segues.EventOverviewToGuestList,
     segues.EventOverviewToAnalytics,
    segues.EventOverviewToMessaging,
     segues.EventOverviewToInformation:
  let destinationVC = segue.destinationViewController as! BaseViewController
  destinationVC.eventData = eventData
  default: break
}

您可以在 ViewController 上使用 EventDataProtocol 来设置 eventData。任何使用 EventDataProtocol 的视图控制器将始终具有由 Segue 设置的事件数据。例如:

protocol EventDataProtocol {
    var eventData: Int? { get set } //Change to your actual type
}
class EventData: UIViewController, EventDataProtocol {
    var eventData: Int?
}

然后在您的准备方法中:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    super.prepareForSegue(segue, sender: sender)
    if var eventDataVC = segue.destinationViewController as? EventDataProtocol {
        eventDataVC.eventData = 5
    }
}

给定

struct EventData {}

定义以下协议

protocol Module0 { var eventData: EventData? { get set } }

并符合您的视图控制器

class GuestListVC: UIViewController, Module0 { var eventData: EventData? }
class AnalyticsVC: UIViewController, Module0 { var eventData: EventData? }
class MessagingVC: UIViewController, Module0 { var eventData: EventData? }
class InformationVC: UIViewController, Module0 { var eventData: EventData? }

向枚举添加属性

extension UIStoryboardSegue {
    enum Segue: String {
        case EventListToEventOverview
        case EventOverviewToGuestList
        case EventOverviewToAnalytics
        case EventOverviewToMessaging
        case EventOverviewToInformation
        static var allRawValues: [String] {
            return
                [
                    Segue.EventListToEventOverview.rawValue,
                    Segue.EventOverviewToGuestList.rawValue,
                    Segue.EventOverviewToAnalytics.rawValue,
                    Segue.EventOverviewToMessaging.rawValue,
                    Segue.EventOverviewToInformation.rawValue
            ]
        }
    }
}

现在它非常简单

class ViewController: UIViewController {
    var eventData = EventData()
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        navigationItem.title = nil
        if var destinationVC = segue.destinationViewController as? protocol<Module0> where UIStoryboardSegue.Segue.allRawValues.contains(segue.identifier!) {
            destinationVC.eventData = eventData
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新