2017-08-29 26 views
0

說我有以下幾點:有條件地轉換失敗

class ContentSelectableViewController<T: NSManagedObject> : UIViewController { //... } 

class PersonSelectionViewController: ContentSelectableViewController<Person> { // ... } 

class PlaceSelectionViewController: ContentSelectableViewController<Place> { // ... } 

然後在這些子類的實例,我有一些代碼:

if let navCtrl = self.navigationController { 


    for viewController in navCtrl.viewControllers.reversed() { 

     if viewController is ContentSelectableViewController { 
      log.info("Worked for \(viewController.description)") 
     } 

     if let vc = viewController as? ContentSelectableViewController { 
      // This should be equivalent to the above. 
     } 
    } 
} 

我的問題是,當我有一堆堆滿了這個泛型基類的子類,它在檢查它們是否爲ContentSelectableViewController時並不總是返回真(進入if語句),我不明白爲什麼。它們從相同的基類繼承而來。

編輯:

我猜這是因爲類的一般性質。對於調用它的子類,if語句的計算結果爲true。

+0

都是爲「是」條件要檢查的viewController類型等於ContentSelectableTableViewController和第二個條件你鑄造的viewController到ContentSelectableTableViewController不同。 – Pushpendra

+0

是的,我知道。這不是問題。問題是爲什麼這些if語句對通用的一個子類評估爲真,而不是另一個。 – horseshoe7

回答

0

因此,它確實與嘗試鍵入檢查泛型類有關。它可以爲一個而不是另一個工作,因爲進行調用的那個隱式添加它的類型。

即(僞SWIFT)

if viewController is ContentSelectableViewController<Person> { //... }

我所做的卻是定義一個協議,最終使這些ContentSelectableViewController<T>可選:

enum ContentSelectionRole: Int { 
    case none = 0 // no selection going on right now. 
    case root // i.e. the one wanting content 
    case branch // an intermediary. think of a folder when looking for a file 
    case leaf // like a file 
} 

enum ContentSelectability: Int { 
    case noSelections = 0 
    case oneSelection = 1 
    case multipleSelections = 2 
} 

protocol ContentSelection { 

    var selectedObjects: [NSManagedObject] { get set } 
    var selectionRole: ContentSelectionRole { get set } 
    var selectionStyle: ContentSelectability { get set } 
    func popToSelectionRootViewController() -> Bool 
    func willNavigateBack(from viewController: UIViewController) 
} 

作出定義:

class ContentSelectableViewController<T: NSManagedObject> : UIViewController, ContentSelection { //... } 

然後,重構orig inal post,得到:

@discardableResult func popToSelectionRootViewController() -> Bool { 

    if let navCtrl = self.navigationController { 

     for viewController in navCtrl.viewControllers.reversed() { 

      if let vc = viewController as? ContentSelection { 
       if vc.selectionRole == .root { 

        vc.willNavigateBack(from: self) 
        navCtrl.popToViewController(viewController, animated: true) 
        return true 
       } 
      } 
     } 
    } 

    return false 
} 

我仍然不完全理解使它失敗的語言方面,但這個解決方案的工作原理。

基於協議的程序設計似乎更加SWIFTY反正...