Voici mon code que je voudrais refactoriser:
let myCell = MyCustomTableViewCell() self.createCell(myCell, reuseIdentifierSsortingng: "myCellIdentifier")
MyCustomTableViewCell est conforme au protocole SetCell, donc cela fonctionne bien. et le protocole SetCell n'est pas un protocole @obj_c. C'est un protocole rapide
private func createCell<T where T:SetCell>(classType: T, reuseIdentifierSsortingng: Ssortingng) -> UITableViewCell { var cell = _tableView.dequeueReusableCellWithIdentifier(reuseIdentifierSsortingng) as T cell.setText() return cell.getCustomCell() }
Et maintenant je refactorise mon code, je voudrais créer le myCell en fonction d'une string, mais la string est exactement la même que mon nom de class. Je ne veux pas utiliser else-if ou switch-case
let myCell: AnyClass! = NSClassFromSsortingng("MyCustomTableViewCell") self.createCell(myCell, reuseIdentifierSsortingng: "myCellIdentifier")
Mais maintenant le myCell qui est AnyClass n'est pas conforme au protocole. Comment puis-je faire ceci?
Vous avez besoin d'un peu plus de code que ça. Vous obtiendrez une AnyClass et non un AnyObject. Vous devez donc créer une instance de ce type. Vous pourriez essayer ceci:
let cellClass: AnyClass! = NSClassFromSsortingng("MyCell") var objectType : NSObject.Type! = cellClass as NSObject.Type! var theObject: NSObject! = objectType() as NSObject var myCell:MyCell = theObject as MyCell
Pour le laisser se conformer à votre protocole, vous pouvez essayer quelques choses:
1. Vous pouvez créer une class de base pour toutes vos cellules conforms à un protocole. Et utilisez cela dans le code ci-dessus au lieu de UITableViewCell. Pour cela, vous pouvez utiliser du code comme ceci:
protocol SetCell { func setcell() {} } class BaseUITableViewCell : UITableViewCell, SetCell { func setcell() {} } class MyCell : BaseUITableViewCell { override func setcell() {} } let cellClass: AnyClass! = NSClassFromSsortingng("MyCell") var objectType : NSObject.Type! = cellClass as NSObject.Type! var theObject: NSObject! = objectType() as NSObject var myCell:BaseUITableViewCell = theObject as BaseUITableViewCell
2. Vous pouvez étendre UITableViewCell avec votre extension comme en ajoutant une extension vide
extension UITableViewCell: SetCell {}
// erreur de compilation:
Declarations from extensions cannot be overridden yet
// Edwin: Etrange, c'est dans la documentation. Donc on dirait que celui-ci est sorti …
3. Vous pouvez définir une variable conforme à un protocole comme celui-ci:
@objc protocol SetCell { func setcell() {} } let cellClass: AnyClass! = NSClassFromSsortingng("MyCell") var objectType : NSObject.Type! = cellClass as NSObject.Type! var myCell2:protocol<SetCell> = objectType() as protocol<SetCell>
class IndexViewController: UIViewController{} let className = "IndexViewController" let bundlePath = NSBundle.mainBundle().bundlePath let bundleFullName = bundlePath.componentsSeparatedBySsortingng("/").last let bundleName = bundleFullName?.componentsSeparatedBySsortingng(".").first let clazz = NSClassFromSsortingng(bundleName! + "." + className)! as! UIViewController.Type let object = clazz.init() // let object1 = Index()