[英]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.