作为tableView(_:,cellForRowAt :)中的一个例子,我想将tableView.dequeueReusableCell返回的单元格(withIdentifier:reuseID,for:indexPath)转换为符合RLMEntityCapableCell协议的UITableViewCell的子类(只是指定了conformers)有一个名为item的变量,它是Object的一个实例,或者是它的一个子类).@H_403_3@
这条路线有效,但双重铸造似乎过度:@H_403_3@
protocol RLMEntityCapableCell: class { var item: Object { get set } } public func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCell(withIdentifier: reuseID,for: indexPath) as! RLMEntityCapableCell // Cast here so we can set item cell.item = items[indexPath.row] return cell as! UITableViewCell // Cast again so the return type is right… }
var cell = tableView.dequeueReusableCell(withIdentifier: reuseID,for: indexPath) as! RLMEntityCapableCell,UITableViewCell
type annotation missing in pattern@H_403_3@
我更愿意指出,为了符合协议,对象必须从UITableViewCell或UICollectionViewCell继承,但协议的基础只能限于类类型而不能进一步.@H_403_3@
编辑:@H_403_3@
这里的想法是为Realm对象提供一个通用数据源,它可以像Array和Dictionary那样利用泛型.每个表视图中使用的单元格将特定于要显示的实体,但数据源只知道该单元格将是符合RLMEntityCapableCell的UITableViewCell的子类.所有数据源需要担心的是告诉单元格需要显示哪个实例(它始终是Object的子类),单元格将从那里获取它并根据需要进行自我配置.@H_403_3@
解决方法
下一个Swift版本(版本4)可能会带来您正在寻找的内容,这是一个名为Class and Subtype Existentials的新功能:@H_403_3@
This proposal brings more expressive power to the type system by allowing Swift to represent existentials of classes and subtypes which conform to protocols.@H_403_3@
The proposal keeps the existing
&
Syntax but allows one of the elements to be eitherAnyObject
or of class type (e.g.,SomeClass & SomeProtocol
).@H_403_3@
然后你可以说:@H_403_3@
var cell = tableView.dequeueReusableCell(withIdentifier: reuseID,for: indexPath) as! UITableViewCell & RLMEntityCapableCell
但是,当然,您将无法使用它来为您的RLMEntityCapableCell协议添加超类要求(如您最初所希望的那样).我们可能需要等待Swift 5