首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查Swift类是否符合协议并实现可选函数?

检查Swift类是否符合协议并实现可选函数?
EN

Stack Overflow用户
提问于 2016-04-07 11:29:07
回答 2查看 23.7K关注 0票数 20

我正在用Swift编写一个帮助函数,用于SpriteKit游戏中,它将检查是否正确设置了碰撞滞留。

我想检查我的GameScene是否实现了协议SKPhysicsContactDeletegate,并且还包含了didBeginContact函数。

我有以下代码,在Xcode的自动完成的帮助下编写的:

代码语言:javascript
复制
    if GameScene(conformsToProtocol(SKPhysicsContactDelegate)) {
        if GameScene(respondsToSelector(didBeginContact(SKPhysicsContact))) {
            print("Self implements SKPhysicsContactDelegate and didBeginContact appears to be present")
        }
    }

然后Xcode抱怨我的conformsToProtocol,抱怨

‘参数标签'(_:)’不匹配任何可用的重载‘

却不知道该怎么解决。它还反对respondsToSelector,声明

‘无法将类型的值(SKPhysicsContact).Type’(又名'SKPhysicsContact.Type')转换为预期的参数类型'SKPhysicsContact‘

如何检查我的GameScene是否符合此协议并实现此功能?

编辑:这是我基于答案的代码:

代码语言:javascript
复制
if GameScene.self is SKPhysicsContactDelegate {
    print("Yes it's a delegate")
}

输出:Yes it's a delegate

代码语言:javascript
复制
let yy = (GameScene.self as? SKPhysicsContactDelegate)?.didBeginContact
print("yy is \(yy)")

输出:yy is nil

代码语言:javascript
复制
if (GameScene.self as? SKPhysicsContactDelegate)?.didBeginContact != nil {
    print("Yes it's a delegate and the function is there")
}

没有输出。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-07 11:44:51

你还在想目标C,拥抱斯威夫特!

假设您的协议如下所示:

代码语言:javascript
复制
@objc protocol SKPhysicsContactDelegate {
    optional func didBeginContact()
}

试试这个:

代码语言:javascript
复制
if let delegate = gameScene as? SKPhysicsContactDelegate {
    delegate.didBeginContact?()
}

或者一条衬里:

代码语言:javascript
复制
(gameScene as? SKPhysicsContactDelegate)?.didBeginContact?()

注意调用中方法名称之后的?吗?这是因为该方法是可选的,如果对象不实现该方法,则不会调用该方法。如果对象不符合SKPhysicsContactDeletegate协议,则不会执行SKPhysicsContactDeletegate分支。

不调用检查方法存在性

若要在调用之前检查方法本身是否存在,只需省略方法调用以获得对该方法的引用,并像检查任何其他变量一样检查它:

代码语言:javascript
复制
if let method = (gameScene as? SKPhysicsContactDelegate)?.didBeginContact {
    print("gameScene conforms to SKPhysicsContactDelegate and implements didBeginContact")
    // Call it later whenever you want
    method()
}

如果您不需要稍后调用它,只需检查一下nil

代码语言:javascript
复制
if (gameScene as? SKPhysicsContactDelegate)?.didBeginContact != nil {
    print("gameScene conforms to SKPhysicsContactDelegate and implements didBeginContact")
}

检查静态方法

检查optional static方法使用相同的方法,但需要类对象而不是类的实例:

代码语言:javascript
复制
if (GameScene.self as? OptionalProtocol.Type)?.staticMethod != nil {
    print("gameScene conforms to OptionalProtocol and implements staticMethod")
}

请注意GameScene.self用于获取对象类型和<protocol>.Type,以将其转换为协议类而不是协议实例。

全样本

附上游乐场、斯威夫特脚本或任何在线Swift编译器的完整样本

代码语言:javascript
复制
import Foundation

@objc protocol OptionalProtocol {
    optional func instanceMethod()
    optional static func staticMethod()
}

class Nothing {}
class Something: OptionalProtocol {}
class Bar: NSObject, OptionalProtocol {
    func instanceMethod() {
        print("Instance method")
    }
}
class Foo: NSObject, OptionalProtocol {
    static func staticMethod() {
        print("Static method")
    }
}

// Cast instances to 'Any' and classes to 'AnyClass'
let nothing: Any = Nothing()
let nothingClass: AnyClass = Nothing.self
let something: Any = Something()
let somethingClass: AnyClass = Something.self
let bar: Any = Bar()
let barClass: AnyClass = Bar.self
let foo: Any = Foo()
let fooClass: AnyClass = Foo.self

nothing is OptionalProtocol // false
(nothing as? OptionalProtocol)?.instanceMethod != nil // false
(nothing as? OptionalProtocol)?.instanceMethod?() // Does nothing
(nothingClass as? OptionalProtocol.Type)?.staticMethod != nil // false
(nothingClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Does nothing

something is OptionalProtocol // true
(something as? OptionalProtocol)?.instanceMethod != nil // false
(something as? OptionalProtocol)?.instanceMethod?() // Does nothing
(somethingClass as? OptionalProtocol.Type)?.staticMethod != nil // false
(somethingClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Does nothing

bar is OptionalProtocol // true
(bar as? OptionalProtocol)?.instanceMethod != nil // true
(bar as? OptionalProtocol)?.instanceMethod?() // Prints 'Instance method'
(barClass as? OptionalProtocol.Type)?.staticMethod != nil // false
(barClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Does nothing

foo is OptionalProtocol // true
(foo as? OptionalProtocol)?.instanceMethod != nil // false
(foo as? OptionalProtocol)?.instanceMethod?() // Does nothing
(fooClass as? OptionalProtocol.Type)?.staticMethod != nil // true
(fooClass as? OptionalProtocol.Type)?.staticMethod?() != nil // Prints 'Static method'
票数 41
EN

Stack Overflow用户

发布于 2016-04-07 11:45:20

respondsToSelector失败,因为它需要一个SKPhysicsContact实例,而不是SKPhysicsContact.type实例。

要检查对象是否实现了接口,可以使用is。例如:

代码语言:javascript
复制
protocol Test {
    func foo();
}

class TestImpl : Test {
    func foo() {
        print("bar")
    }
}

let a = TestImpl()
let b = String()
print(a is Test) // true
print(b is Test) // false
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36474864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档