I run into an interesting behaviour which I don't understand. Here is code that produces this behaviour:
import UIKit
protocol UIViewNibLoading {
static var nibName: String { get }
}
extension UIView : UIViewNibLoading {
static var nibName: String {
return String(describing: self)
}
}
extension UIViewNibLoading where Self : UIView {
static func loadFromNib<T: UIViewNibLoading>() -> T {
print(T.nibName)
print(nibName)
return UINib(nibName: nibName, bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! T
// CRASH: return UINib(nibName: T.nibName, bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! T
}
}
Here is output from console when this code is executed:
UIView
MyCustomViewSubclass
When I call then loadFromNib
method on my custom class. It produces two different behaviours depending on how do I get the nibName
.
- T.nibName: This returns string
UIView
- nibName: This returns string
MyCustomViewSubclass
Do you know what is going on here? Why self
and T
is not the same object during the runtime? Here is another one interesting thing I've found out. Here is what you can see in debugger when you put breakpoint into nibName
getter:
This is called as:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == WidgetAddTableViewController.SectionIndexRecent {
return WidgetAddHeaderView.loadFromNib()
} else if section == WidgetAddTableViewController.SectionIndexFreeAndPremium {
return WidgetAddFilterHeaderView.loadFromNib()
}
return nil
}
Thanks for any explanation.