我有一个像这样的闭包/块
typealias TableViewConfigureBlock = (AnyObject?, AnyObject?) -> Void
它需要2个参数:单元格对象和模型对象。由于我希望它是通用的,我使用了AnyObject。
当我像这样定义块
时var configureCellBlock : (ContactTableViewCell, Contact) -> Void = {cell, contactInfo in
cell.nameLabel.text = contactInfo.name
cell.numberLabel.text = contactInfo.number
cell.profileImageView.image = contactInfo.image
}
编译器抛出错误说
'AnyObject?' is not a subtype of 'ContactTableViewCell'
答案 0 :(得分:3)
您的typedef
定义了实际关闭的不同参数。我的一般例子将如下所示:
typealias MyClosureType = (AnyObject?, AnyObject?) -> ()
关键是你定义的闭包必须具有相同的界面,如:
var closure: MyClosureType = { (first: AnyObject?, second: AnyObject?) -> () in
// ...
}
在封闭体内部,你可以检查参数的类型,比如
let cell = first as? UITableViewCell
let contactInfo = second as? String
if cell != nil && contactInfo != nil {
// do the tasks
} else {
println("ops, those parameters are not what I expected")
}
以后您可以使用AnyObject
参数调用块,例如:
closure(12, "SampleText");
closure(nil, ["1024", "2048"]);
等,但这里的关键点是,当您定义闭包时,您必须保留参数' typealias
定义的类型。
如果您的代码:
typealias TableViewConfigureBlock = (AnyObject?, AnyObject?) -> Void
VS
// I'm incorrect
var configureCellBlock : TableViewConfigureBlock = { (cell: ContactTableViewCell, contactInfo: Contact) -> Void in
// ...
}
其中接口和实现具有不同的类型。如果您这样写,您将看到实现违反界面的方式:
// I'm incorrect
var configureCellBlock : (AnyObject?, AnyObject?) -> Void = { (cell: ContactTableViewCell, contactInfo: Contact) -> Void in
// ...
}
你需要在这里做一些类似的事情:
// I'm correct now
var configureCellBlock : (AnyObject?, AnyObject?) -> Void = { (cell: AnyObject?, contactInfo: AnyObject?) -> Void in
// ...
}
答案 1 :(得分:1)
这是一段更新的代码。
var configureCellBlock : TableViewConfigureBlock = ({
(cell: AnyObject?, contact: AnyObject?) in
var tableCell = cell as? ContactTableViewCell
var contactInfo = contact as? Contact
if tableCell && contactInfo {
tableCell!.nameLabel.text = contactInfo!.name
tableCell!.numberLabel.text = contactInfo!.number
tableCell!.profileImageView.image = contactInfo!.image
}
})
首先,您没有使用已定义的闭包类型。正如您所看到的,我通过声明configureCellBlock
类型TableViewConfigureBlock
来介绍它。
接下来,您的闭包参数类型必须与类型别名中提供的类型相匹配。因此,单元格和联系人必须是AnyObject?
(cell: AnyObject?, contact: AnyObject?)
在闭包的主体中,首先必须将AnyObject
类型对象向下转换为可以使用的对象。所以在下面的代码中你就是这么做的。
var tableCell = cell as? ContactTableViewCell
var contactInfo = contact as? Contact
由于参数为Optional
类型,您可能需要检查它们是否为零。如果不是,则将联系人信息设置为相应的单元格元素。