簡體   English   中英

從泛型返回類型獲取實際類型

[英]Getting the actual type from a generic return type

我在加載特定類型和名稱的筆尖的UIView上有一個擴展:

extension UIView {

    class func fromNib<T : UIView>() -> T? {

        guard let nib = Bundle(for: T.self).loadNibNamed(String(describing: T.self), owner: nil, options: nil)?[0]
            else {
                return nil
        }
        return nib as? T
    }
}

現在在我的Hint類(它是UIView的子類)中,我像這樣使用上面的擴展:

 if let view = Hint.fromNib(){
        self.addSubview(view)
        view.frame = self.bounds         
 }

這不起作用,因為T.self的結果T.self是 UIView,即使 Hint 是調用fromNib方法的類。 如果我嘗試對這樣的類進行硬編碼:

Bundle(for: Hint.self).loadNibNamed(String(describing: Hint.self), owner: nil, options: nil)

然后一切正常。 如何獲取實際調用fromNib()方法的類的類型名稱?

這是我的提示類:

class Hint:UIView {

     required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        if let view = UIView.fromNib(){
            self.addSubview(view)
            view.frame = self.bounds

        }

    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        if let view = UIView.fromNib(){
            self.addSubview(view)
            view.frame = self.bounds
        }
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        if let view = UIView.fromNib(){
            self.addSubview(view)
            view.frame = self.bounds
        }
    }

}

所以一切都非常簡單。 一個 nib 文件只有一個標簽和一個圖像視圖,但我想這與當前問題幾乎無關。

您想知道調用fromNib()的類的類型,它是類方法中的self

extension UIView {
    class func fromNib<T : UIView>() -> T? {
        guard
            let nibs = Bundle(for: self).loadNibNamed(String(describing: self), owner: nil, options: nil),
            let nib = nibs.first
            else {
                return nil
        }

        return nib as? T
    }
}

下列:

if let viewFromXib = MyXib.fromNib(){            
    view.addSubview(viewFromXib)
    viewFromXib.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30))
    print(viewFromXib)
}

作品和版畫:

<TESTS.MyXib: 0x7f9531408aa0; frame = (0 0; 30 30); autoresize = W+H; layer = <CALayer: 0x60000002b8e0>>

我不太明白返回類型T是如何推斷的。


更新:

我正在研究如何推斷返回類型T ,答案是:不是。

這個:

class func fromNib() -> UIView? {
    guard
        let nibs = Bundle(for: self).loadNibNamed(String(describing: self), owner: nil, options: nil),
        let nib = nibs.first
        else {
            return nil
    }

    return nib as? UIView
}

是等價的。

所以即使這個答案是在解決問題,它也沒有回答問題。

我使用完全相同的方法遇到了完全相同的問題,甚至將其命名為相同的。 我無法使用當前的類類型,因為編譯器假定它是UIView而不是它的子類。

發生的情況是Hint.fromNib()最終與UIView.fromNib()完全相同,因為T不依賴於它被調用的類,所以T被推斷為UIView 您需要做的是通過指定您期望獲得的視圖類型來幫助編譯器推斷正確的類型。

let hint: Hint? = UIView.fromNib()

我要補充的是,雖然您正確使用了guard ,但first[0]更安全,因此我會將您的方法更改為如下所示:

let bundle = Bundle(for: T.self)
let nib = bundle.loadNibNamed(String(describing: T.self), owner: nil, options: nil)
guard let view = nib?.first as? T else {
  return nil
}
return view

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM