我仍然无法理解 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.

ios – 类型不符合协议的更多相关文章

  1. ios – 类型不符合协议

    我仍然无法理解Swift中泛型的一些微妙之处.我定义了以下类型:viewForValue现在我定义了以下功能.我希望T是一个符合协议SomeProtocol的UIView.但是,当我执行代码时,我收到以下编译错误:似乎在where子句中我不能指定不实现协议的类.这是为什么?

  2. ios – 将Swift项目转换为易于使用的Cocoapods框架

    编辑1:我更新了项目,因此它已经具有框架结构,我只需要弄清楚我将如何向开发人员提供对自定义部件的访问权限.编辑2:我得到了一个答案,但我认为这个问题可能很容易被误解.目标是使其行为和行为像UICollectionView(与委托,数据源,…

  3. ios – 如何在Swift中解包数组元素? (即数组为数组)

    假设我有一个String数组,我想将它映射到一个Int数组我可以使用map功能:Numbers现在是一个Int?数组,但我想要一个Int数组.我知道我可以这样做:但这似乎并不是很迅速.从Int数组转换?对于ArrayofInt,需要使用相当多的样板函数来调用filter和map.有更快捷的方法吗?解决方法更新:Xcode7.2Swift2.1.1

  4. ios – Swift:方法重载只在返回类型上有所不同

    我一直在看Swift类,其中定义了两种方法,它们的返回类型不同.我不习惯使用允许这种语言的语言,所以我去寻找描述它如何在Swift中工作的文档.我在任何地方都找不到任何东西.我本来期望在Swift书中有关于它的整个部分.这记录在哪里?

  5. ios – Swift中没有输入参数的通用函数?

    我有一个通用的Swift函数,如下所示:编译器没有错误,但我不知道如何调用此函数.我试过了:但它不起作用.如何在没有输入参数的情况下在Swift中调用Generic函数?解决方法你需要通过一些调用上下文告诉Swift返回类型是什么:注意,在后一种情况下,只有当someCall采用类似于Any的模糊类型作为其参数时,才需要这样做.相反,someCall被指定为[Int]作为参数,函数本身提供上下文,你可以只写someCall事实上,有时可以非常推断出背景!

  6. ios – swift函数返回一个Array

    我学习Swift,我可以理解如何创建一个简单的函数,它接收一个Array并返回一个Array.我的代码:我得到的红色错误是:引用通用类型“Array”需要解决方法在SwiftArray中是通用类型,所以你必须指定什么类型的数组包含.例如:如果你希望你的函数是通用的,那么使用:如果您不想指定类型或具有通用功能使用任何类型:

  7. ios – 嵌套递归函数

    我试图做一个嵌套递归函数,但是当我编译时,编译器崩溃.这是我的代码:编译器记录arehere解决方法有趣的…它似乎也许在尝试在定义之前捕获到内部的引用时,它是bailing?以下修复它为我们:当然没有嵌套,我们根本没有任何问题,例如以下工作完全如预期:我会说:报告!

  8. ios – 键入’ViewController’不符合协议’UICollectionViewDataSource’

    解决方法您必须在ViewController类中实现这两个方法:附:–您的函数原型应该与上述函数完全匹配(如果存在,请删除任何’!

  9. ios – Swift错误:无法将不可变值作为inout参数传递:’pChData’是’let’常量

    解决方法您正在尝试访问/修改pChData参数,除非您将其声明为inout参数,否则您无法访问/修改该参数.了解有关inout参数here的更多信息.请尝试使用以下代码.

  10. ios – Swift:不能下标'[UIViewController]类型的值吗?

    我试图弄清楚如何在Xcode7(iOS9)上的Swift中解决这个问题,我也遇到了这个错误:Cannotsubscriptavalueoftype‘[UIViewController]?’withanindexoftype‘Int’任何建议表示赞赏.谢谢.我的代码:解决方法尝试:但是,写一下会更安全:另一种选择:这样做的好处是它安全,但不需要将函数的其余部分放在if块中.

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部