我可以在ObjC中从string中实例化类.例如,我通过子类化UITableViewCell定义了新的Dbcell类,并使用以下代码从name实例化类:
Dbcell *cell=[tableView dequeueReusableCellWithIdentifier:cellClassname]; if (cell==nil) { Class cellClass=NSClassFromString(cellClassname); cell=[cellClass alloc]; cell=[cell initWithStyle:cellStyle reuseIdentifier:cellClassname]; }
现在我需要将代码迁移到Swift,我在Swift中重新定义了Dbcell类:
class Dbcell: UITableViewCell { var label:String? var key:String? var managedobject:NSManagedobject? var delegate:AnyObject? convenience override init(style: UITableViewCellStyle,reuseIdentifier: String!) { self.init(style: style,reuseIdentifier: reuseIdentifier) self.textLabel.font=UIFont.preferredFontForTextStyle(UIFontTextStyleCaption1) self.backgroundColor=UIColor.blackColor() self.textLabel.backgroundColor=UIColor.blackColor() } }
Swift更加静态类型化,这使得它在运行时更加安全.例如,如果任何字符串都是错误的,你将崩溃(或者最好悄悄地做什么,这可能比崩溃更糟)并且编译器无法为你捕获它.
好的,但你如何处理这种模式?在Swift中,IMO的最佳方式是显式并创建映射.
let cellMapping = [ "Dbcell": Dbcell.self,] if let cellClass = cellMapping[cellClassName] { let cell = cellClass(style: cellStyle,reuseIdentifier: cellClassName) // use cell }
现在,当您重构并更改Dbcell的名称,但错过了Storyboard中的字符串时,一切都将按预期继续工作,而不是像在ObjC中那样崩溃或悄然失败.
Swift对这些映射也非常聪明.上面的cellMapping类型是[String:Dbcell.Type],所以如果你有一个特殊的初始化Dbcell,它就可用了.但如果你的字典看起来像:
let cellMapping = [ "Dbcell": Dbcell.self,"OtherCell": UITableViewCell.self ]
那么类型是[String:UITableViewCell.Type]. Swift自动计算出涵盖所有值的最具体的类.如果你在这个列表中添加了一个没有实际使用的方法的类型,Swift可以在编译时捕获它.如果你犯了一个错误并添加了一些甚至不是表格视图的单元格:
let cellMapping = [ "Dbcell": Dbcell.self,"OtherCell": UITableViewCell.self,"BadCell": UICollectionViewCell.self ]
然后Swift会给你一个编译时警告,你已经创建了一个AnyObject.这对编写安全但灵活的代码非常好,所有这些都是为了字典的成本.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。