“AnyObject?不是CustomClass的子类型

时间:2014-07-07 11:07:02

标签: ios swift

我有一个像这样的闭包/块

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'

2 个答案:

答案 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类型,您可能需要检查它们是否为零。如果不是,则将联系人信息设置为相应的单元格元素。