2017-01-02 48 views
3

我有調用此方法的一個問題:錯誤:無法推斷通用參數'T'。

func setUpFeedbackForm<T:UIViewController>(viewController: T, 
             viewForScreenshot: UIView, 
             completionHandler: @escaping() ->()) 
                where T:FeedbackFormDelegate { ... } 

這個包裝函數內部:

public class func setUpFeedbackFormWrapper(viewController: UIViewController, 
             viewForScreenshot: UIView, 
             completionHandler: @escaping() ->()) { 

    setUpFeedbackForm(viewController: viewController, 
        viewForScreenshot: viewForScreenshot, 
        completionHandler: completionHandler) 
} 

我得到錯誤:通用參數「T」無法推斷。我明白錯誤意味着什麼,但我不知道如何正確實施此調用。此外,爲什麼我有這個包裝的原因是,我想公開func setUpFeedbackForm obj-c代碼,我不能直接導入到obj-c,因爲swift的泛型。

你能告訴我調用它的正確方法嗎?

+2

你能解釋一下爲什麼你在這裏使用泛型? – matt

回答

1

您對viewController參數的兩個約束需要滿足時調用setUpFeedbackForm

  • 繼承自UIViewController
  • 符合FeedbackFormDelegate

,並setUpFeedbackFormWrapper滿足只有一個,因此編譯器不知道如何處理另一個。

該問題是由Swift的限制引起的,它不能直接表示滿足類繼承和協議一致性的變量/參數,除非使用泛型來打破Objective-C兼容性。

因此Objective-C中的有效UIViewController<FeedbackFormDelegate>構造在Swift中沒有直接等效。

一種解決方法,以這種限制是聲明暴露所述類繼承和協議一致性參數作爲兩個不同的參數的第三方法,和調用該方法從兩個Objective-C兼容和Swift -only版本。

func setUpFeedbackForm<T:UIViewController>(viewController: T, 
         viewForScreenshot: UIView, 
         completionHandler: @escaping() ->()) 
    where T:FeedbackFormDelegate { 
     setupFeedbackFormImpl(viewController: viewController, 
           feedbackFormDelegate: viewController, 
           viewForScreenshot: viewForScreenshot, completionHandler: completionHandler) 
} 

func setupFeedbackFormImpl(viewController: UIViewController, 
          feedbackFormDelegate: FeedbackFormDelegate, 
          viewForScreenshot: UIView, 
          completionHandler: @escaping() ->()) { 
    // actual code here 
} 

public func setUpFeedbackFormWrapper(viewController: UIViewController, 
            viewForScreenshot: UIView, 
            completionHandler: @escaping() ->()) { 

    guard let feedbackFormDelegate = viewController as? FeedbackFormDelegate else { 
     // you can also report errors here, if you want to 
     // forbid runtime calls with controllers that are not FeedbackFormDelegate 
     return 
    } 
    setupFeedbackFormImpl(viewController: viewController, 
          feedbackFormDelegate: feedbackFormDelegate, 
          viewForScreenshot: viewForScreenshot, 
          completionHandler: completionHandler) 
} 

如果我們認爲在SOLID編程方面,那麼這個解決方法如下接口分離原則,我們收到的視圖控制器東西一個參數,而另一個爲代表的東西,即使它們指向背後的同一個物體

相關問題