ios – 类型不符合协议

我仍然无法理解 Swift中泛型的一些微妙之处.我定义了以下类型:
protocol SomeProtocol {
    func setValue(value: Int)
}

class ProtocolLabel : UILabel,SomeProtocol {
    func setValue(value: Int) {

    }
}

class ProtocolImageView : UIImageView,SomeProtocol {
    func setValue(value: Int) {
    }
}

viewForValue(2)
现在我定义了以下功能.我希望T是一个符合协议SomeProtocol的UIView.

func viewForValue<T where T: SomeProtocol,T: UIView>(param: Int) -> UIView {
    var someView: T
    if param > 0 {
        someView = ProtocolLabel() as T
    } else {
        someView = ProtocolImageView() as T
    }
    someView.setValue(2)
    someView.frame = CGRectZero
    return someView
}

但是,当我执行代码时,我收到以下编译错误

viewForValue(2) // <-- Type 'UIView' does not conform to protocol 'SomeProtocol'

似乎在where子句中我不能指定不实现协议的类.这是为什么?

提前致谢.

解决方法

viewForValue应该返回一个继承自UIView并实现SomeProtocol的类.
您已经定义了两个没有直接关系的类 – 它们只是从UIView继承并实现SomeProtocol.

函数必须确定返回类型时,两个类继承的直接具体类型是UIView,这就是viewForValue返回的内容.

为了解决这个问题,你必须通过创建一个继承自UIView并实现SomeProtocol的第三类来创建两个类之间的直接和具体的关系:

protocol SomeProtocol {
    func setValue(value: Int)
}

class SomeClass: UIView,SomeProtocol {
    func setValue(value: Int) {

    }
}

class SomeSubclass : SomeClass {
}

class SomeOtherSubclass : SomeClass {
}

func viewForValue<T where T: SomeProtocol,T: SomeClass>(param: Int) -> T {
    var someView: T
    if param > 0 {
        someView = SomeSubclass() as T
    } else {
        someView = SomeOtherSubclass() as T
    }
    someView.setValue(2)
    someView.frame = CGRectZero
    return someView
}

viewForValue(2)

附录:阅读下面的OP评论,目的是动态实例化从UIView继承的现有UIKit类.因此,建议的解决方案不适用.

我认为通过实现SomeProtocol来扩展UIView应该可行:

protocol SomeProtocol {
    func setValue(value: Int)
}

extension UIView : SomeProtocol {
    func setValue(value: Int) {
    }
}

func viewForValue<T where T: SomeProtocol,T: UIView>(param: Int) -> UIView {
    var someView: T
    if param > 0 {
        someView = UILabel() as T
    } else {
        someView = UIImageView() as T
    }
    someView.setValue(2)
    someView.frame = CGRectZero
    return someView
}

但看起来有一个编译器错误.操场上的此代码显示一条消息,指出:

Communication with the playground service was interrupted unexpectedly.
The playground service “com.apple.dt.Xcode.Playground” may have generated a crash log.

而在iOS应用程序中,由于分段错误,编译失败11.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...