【问题标题】:AnyObject not working in Xcode8 beta6?AnyObject 在 Xcode8 beta6 中不起作用?
【发布时间】:2016-08-19 07:16:35
【问题描述】:

在 Xcode8 beta6 中,以下代码会导致警告:'is' test is always true。但它不会打印通行证。

    struct TestStruct {
    }

    //warning: 'is' test is always true
    if TestStruct() is AnyObject {
        print("pass")
    }

下面的代码会引发警告:Conditional cast from 'T' to 'AnyObject' always succeeds

public static func register<T>(_ protocolType: T.Type, observer: T) {

    //Warning: Conditional cast from 'T' to 'AnyObject' always succeeds
    guard let object = observer as? AnyObject else {
        fatalError("expecting reference type but found value type: \(observer)")
    }
    //...
}

【问题讨论】:

  • 看起来像一个编译器警告系统错误。结构不能符合类协议 AnyObject
  • 不错的发现 - 你应该 file a bug report
  • 谢谢。错误报告:bugs.swift.org/browse/SR-2420
  • 我前段时间看到了您的 SwiftNoficationCenter 并且(未成功)尝试使该运行时检查成为编译时检查:stackoverflow.com/questions/37707450/…。但是现在(据我了解) anything 可以包装到一个对象中(根据您的框架的需要,使用弱引用)。因此,将值注册为观察者应该可以正常工作。
  • @MartinR 感谢您的回复。但它不起作用。一旦 _SwiftValue 被分配给弱引用。弱引用变为 nil。我不知道底层机制发生了什么,但是我不认为可以观察到值类型,因为它是通过副本传递的。

标签: ios swift xcode swift3 xcode8-beta6


【解决方案1】:

警告按预期工作:但是,TestStruct() is AnyObjectfalse 返回没有

此答案的先前版本感知到警告,

'is' 测试总是正确的

作为错误,并包含一些关于为什么这种感知错误警告会出现的讨论。然而,TestStruct() is AnyObject 在运行时被评估为false,这被认为是预期的行为。

鉴于bug report filed by the OP (SR-2420) 的cmets,情况似乎相反:由于Xcode 8/beta 6,is 测试应该总是评估为true,并且错误OP:s 的帖子是 TestStruct() is AnyObject 在运行时计算为 false 的事实。

Joe Groff writes:

这是正确的,因为现在一切都连接到AnyObject

...

is/as AnyObject 现在对所有类型总是成功。它的行为 符合预期。


用于将 Swift 值转换为 Obj-C 对象的新 SwiftValue

(有关更多详细信息,请参阅下面 cmets 中的讨论,谢谢@MartinR)

似乎没有明确实现的 Swift 值可以通过例如桥接到 Obj-C 对象。符合_ObjectiveCBridgeable(参见例如the following Q&A for details regarding _ObjectiveCBridgeable),将改为自动使用新的SwiftValue 框来允许转换为Obj-C 对象。

swift/stdlib/public/runtime/SwiftValue.mm 的初始提交消息如下:

运行时:实现一个不透明的“SwiftValue”ObjC 类来保存桥接值

如果没有更好的将 Swift 值映射到 Objective-C 的方法 用于桥接目的的对象,我们可以回退到将值装箱 一类。这个类除了存在之外没有任何公共接口 NSObject-conforming 在 Objective-C 中,但被 Swift 识别 运行时,以便它可以动态转换回装箱类型。

【讨论】:

  • 感谢您的回复。我提交了一个错误报告:bugs.swift.org/browse/SR-2420。我不使用 AnyObject 约束 T 的原因是我创建了一个框架SwiftNotificationCenter 用于一对多通信。用户将 Protocol.Type 作为参数传递。
  • 是的,我上面的评论从纯 Swift 值转换为 AnyObject 成功,type(of: o) 打印“_SwiftValue”。这就是我找到源文件的方式。所以似乎任意值都被装箱为 AnyObject。
  • @MartinR 啊,beta 6 中的新魔法,不知道这个。刚刚注意到 OP 提交的错误报告有一些活动,主要链接到 this pull request,其中包括您上面链接到的 SwiftValue 源(描述:“对 AnyObject 的动态转换应该成功任意源类型,因为我们总是可以创建一个 SwiftValue。”)。因此,OPs 问题中的警告似乎不是错误,而是is 测试在运行时失败的事实。
  • @MartinR 谢谢。最后一点,_ObjectiveCBridgeable 似乎仍将作为详细实现的隐式转换持续存在,而如果先验不可用(对于某些给定类型),则将使用 _SwiftValue 框。
【解决方案2】:

长话短说。

检查值是否具有引用类型:

if type(of: value) is AnyClass {
    // ...
}

检查类型是否为引用类型:

if SomeType.self is AnyClass {
   // ...
}

更多有用的答案:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 2017-02-08
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多