当前位置: 首页 > 面试题库 >

从Any中失败投放Swift?协议

何升
2023-03-14
问题内容

仅供参考:在此处引发的Swift错误:https :
//bugs.swift.org/browse/SR-3871

我遇到一个奇怪的问题,即强制转换不起作用,但控制台将其显示为正确的类型。

我有公开协议

public protocol MyProtocol { }

然后,我使用一个返回实例的公共方法在一个模块中实现此功能

internal struct MyStruct: MyProtocol { }

public func make() -> MyProtocol { return MyStruct() }

然后,在我的视图控制器中,我以该对象作为发送者触发segue

let myStruct = make()
self.performSegue(withIdentifier: "Bob", sender: myStruct)

到目前为止一切都很好。

问题出在我的prepare(for:sender:)方法上。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "Bob" {
        if let instance = sender as? MyProtocol {
            print("Yay")
        }
    }
}

但是,将实例强制转换为MyProtocol始终返回nil

当我po sender as! MyProtocol在控制台中运行时,它给了我错误Could not cast value of type '_SwiftValue' (0x1107c4c70) to 'MyProtocol' (0x1107c51c8)。但是,po sender将输出一个有效的Module.MyStruct实例。

为什么这种转换不起作用?

(我已经设法通过将协议包装在结构中来解决它,但是我想知道为什么它不能按原样工作,以及是否有更好的方法来修复它)


问题答案:

这是一个非常奇怪的错误-看起来好像是通过将一个实例放入a _SwiftValue并将其静态键入为,将实例桥接到Obj-
C时发生的Any(?)。然后,该实例不能转换为它所遵循的给定协议。

根据Joe
Groff在您提交的错误报告的评论中所说:

这是一般“运行时动态转换在需要桥接到协议时不桥接”错误的一个实例。由于发件人被视为_SwiftValue对象类型,并且我们试图获取不符合它的协议,因此我们在不尝试桥接类型的情况下放弃了。

一个更简单的示例是:

protocol P {}
struct S : P {}

let s = S()

let val : Any = s as AnyObject // bridge to Obj-C as a _SwiftValue.

print(val as? P) // nil

足够奇怪的是,首先强制AnyObject转换为协议,然后强制转换为协议,似乎可以正常工作:

print(val as AnyObject as! P) // S()

因此看来,静态键入它AnyObject使Swift也会检查桥接类型的协议一致性,从而使转换成功。正如Joe
Groff在另一条评论中所述,这样做的原因是:

运行时存在许多错误,它们仅尝试将某些转换转换到一个深度级别,而在执行其他转换后则不行(因此AnyObject-> bridge->
Protocol可能起作用,但是Any-> AnyObject-> bridge-> Protocol不起作用’)。它 应该
无论如何都可以工作。



 类似资料:
  • 问题内容: 我有以下代码。如何解决最后一行中的错误? 问题答案: 更新: 此问题已在Swift 1.2+(Xcode 6.3+)中修复。Xcode 6.3 beta发行说明说: 现在,只要没有关联类型,动态类型转换(“ as!”,“ as?”和“ is”)就可以使用Swift协议类型。 只能检查协议一致性(其包括,,和用) 协议。不是。 请参阅Swift书中的“ 检查协议一致性”部分。 注意 仅当

  • 问题内容: 我不明白何时在Swift中使用AnyObject以及何时使用Any。 就我而言,我有字典 [字串:???] ??? :可以是Int,Double,Float,String,Array,Dictionary 有人可以向我解释Any和AnyObject之间的区别以及在我的情况下使用哪个。 阿拉克 问题答案: 仅适用于引用类型(类),适用于值和引用类型。 所以你应该去。 类型转换为Any和A

  • 本文向大家介绍Swift投射,包括了Swift投射的使用技巧和注意事项,需要的朋友参考一下 示例 将函数应用于集合/流并创建新的集合/流称为投影。            

  • 问题内容: 我正在尝试使用JSch(0.1.44-1)通过ssh连接到远程sftp服务器,但是在“ session.connect();”期间 我收到此异常: 来自JSch的日志: 我可以使用linux sftp命令登录到远程服务器。我试图在互联网上找到任何线索,但是失败了。 linux sftp命令的调试输出: 问题答案: SSH客户端和服务器在几个地方尝试并同意一个通用实现。我知道的两个是加密

  • 我正在尝试使用SSL调用web服务。它给出了以下错误:

  • 我安装了:“CPAN isntall crypt::ssleay”,因此“fs.cgi:错误500 SSL协商失败:”的错误更改为“请求fs.cgi时失败:SSL协商失败:在/usr/local/share/perl5/lwp/protocol/http.pm行25在/usr/local/share/perl5/lwp/protocol/http.pm行25” 怎么解决这个?我搜索了这个论坛,但问