@property (strong,nonatomic) UIViewController<UITableViewDelegate> *thing;
我想在Swift的这个Objective-C代码中实现一个属性.所以这里是我试过的:
class AClass<T: UIViewController where T: UITableViewDelegate>: UIViewController { var thing: T! }
这个编译.当我从故事板添加属性时,我的问题来了. @IBOutlet标签生成编译器错误.
class AClass<T: UIViewController where T: UITableViewDelegate>: UIViewController { @IBOutlet weak var anotherThing: UILabel! // error var thing: T! }
错误:
Variable in a generic class cannot be represented in Objective-C
解决方法
我遇到了同样的问题,也尝试了通用的方法.最终,通用方法打破了整个设计.
在重新考虑了这个问题之后,我发现一个不能用于完全指定一个类型的协议(换句话说,必须附加类型信息等类型)不太可能是一个完整的.此外,虽然声明ClassType< ProtocolType>的Objc风格方便,它忽略了由协议提供的抽象的好处,因为这样的协议并没有真正提高抽象级别.此外,如果这种声明出现在多个地方,必须重复.更糟糕的是,如果这种类型的多个声明是相互关联的(可能是一个单一的对象将在其周围传递),程序变得脆弱而难以维护,因为如果一个地方的声明需要更改,那么所有相关的声明必须也改变了.
解
如果属性的用例涉及协议(例如ProtocolX)和类的某些方面(例如ClassX),则可以考虑以下方法:
>声明一个附加协议,继承自ProtocolX,并附加了ClassX自动满足的方法/属性要求.像下面的例子一样,一个方法和一个属性是额外的要求,这两个都是UIViewController自动满足的.
protocol CustomTableViewDelegate: UITableViewDelegate { var navigationController: UINavigationController? { get } func performSegueWithIdentifier(identifier: String,sender: AnyObject?) }
>声明一个附加协议,并具有ClassX类型的附加只读属性.这种方法不仅可以全面使用ClassX,而且还具有不需要实现子类ClassX的灵活性.例如:
protocol CustomTableViewDelegate: UITableViewDelegate { var viewController: UIViewController { get } } // Implementation A class CustomViewController: UIViewController,UITableViewDelegate { var viewController: UIViewController { return self } ... // Other important implementation } // Implementation B class CustomClass: UITableViewDelegate { private var _aViewControllerRef: UIViewController // Could come from anywhere e.g. initializer var viewController: UIViewController { return _aViewControllerRef } ... // UITableViewDelegate methods implementation }
PS.上面的代码段仅供演示,不推荐将UIViewController和UITableViewDelegate混合在一起.
为Swift 2编辑:感谢@ Shaps的评论,可以添加以下内容以节省在任何地方实现所需的属性.
extension CustomTableViewDelegate where Self: UIViewController { var viewController: UIViewController { return self } }