如何根据Swift中的String创建对象?

时间:2014-09-08 15:57:56

标签: ios generics swift protocols conform

这是我想要重构的代码:

let myCell = MyCustomTableViewCell()
self.createCell(myCell, reuseIdentifierString: "myCellIdentifier")

MyCustomTableViewCell符合SetCell协议,因此工作正常。并且SetCell协议不是@obj_c协议。这是一个快速的协议

private func createCell<T where T:SetCell>(classType: T, reuseIdentifierString: String) -> UITableViewCell {
  var cell = _tableView.dequeueReusableCellWithIdentifier(reuseIdentifierString) as T
  cell.setText()
  return cell.getCustomCell()
}

现在我重构我的代码,我想根据字符串创建myCell,但字符串与我的类名完全相同。我不想使用else-if或switch-case

let myCell: AnyClass! = NSClassFromString("MyCustomTableViewCell")
self.createCell(myCell, reuseIdentifierString: "myCellIdentifier")

但是现在作为AnyClass的myCell不符合协议。 我怎么能这样做?

2 个答案:

答案 0 :(得分:6)

您需要更多代码。您将获得AnyClass而不是AnyObject。因此,您需要创建该类型的实例。你可以试试这个:

let cellClass: AnyClass! = NSClassFromString("MyCell")
var objectType : NSObject.Type! = cellClass as NSObject.Type!
var theObject: NSObject! = objectType() as NSObject
var myCell:MyCell = theObject as MyCell

为了让它符合您的协议,您可以尝试以下几点:

<强> 1。您可以为符合协议的所有单元格创建基类。并在上面的代码中使用它而不是UITableViewCell。为此,您可以使用以下代码:

protocol SetCell {
    func setcell() {}
}
class BaseUITableViewCell : UITableViewCell, SetCell {
    func setcell() {}
}
class MyCell : BaseUITableViewCell {
    override func setcell() {}
}

let cellClass: AnyClass! = NSClassFromString("MyCell")
var objectType : NSObject.Type! = cellClass as NSObject.Type!
var theObject: NSObject! = objectType() as NSObject
var myCell:BaseUITableViewCell = theObject as BaseUITableViewCell

<强> 2。您可以使用扩展程序扩展UITableViewCell,例如添加空扩展

extension UITableViewCell: SetCell {}

//编译时错误:

Declarations from extensions cannot be overridden yet

// Edwin:很奇怪,这是在文档中。所以看起来这个就出来了......

第3。您可以定义符合此协议的变量:

@objc protocol SetCell {
    func setcell() {}
}

let cellClass: AnyClass! = NSClassFromString("MyCell")
var objectType : NSObject.Type! = cellClass as NSObject.Type!
var myCell2:protocol<SetCell> = objectType() as protocol<SetCell>

答案 1 :(得分:0)

class IndexViewController: UIViewController{}

let className = "IndexViewController"

let bundlePath = NSBundle.mainBundle().bundlePath
let bundleFullName = bundlePath.componentsSeparatedByString("/").last
let bundleName = bundleFullName?.componentsSeparatedByString(".").first
let clazz = NSClassFromString(bundleName! + "." + className)! as! UIViewController.Type
let object = clazz.init()
// let object1 = Index()