gpt4 book ai didi

swift - Swift 中的@selector()?

转载 作者:行者123 更新时间:2023-11-30 13:35:12 25 4
gpt4 key购买 nike

我正在尝试创建 NSTimerSwift但我遇到了一些麻烦。

NSTimer(timeInterval: 1, target: self, selector: test(), userInfo: nil, repeats: true)
test()是同一个类中的一个函数。

我在编辑器中收到错误:

Could not find an overload for 'init' that accepts the supplied arguments



当我更改 selector: test()selector: nil错误消失。

我试过了:
  • selector: test()
  • selector: test
  • selector: Selector(test())

  • 但是没有任何效果,我在引用资料中找不到解决方案。

    最佳答案

    Swift 本身不使用选择器——在 Objective-C 中使用选择器的几种设计模式在 Swift 中的工作方式不同。 (例如,在协议(protocol)类型上使用可选链接或 is/as 测试而不是 respondsToSelector: ,并尽可能使用闭包而不是 performSelector: 以获得更好的类型/内存安全性。)
    但仍有许多重要的基于 ObjC 的 API 使用选择器,包括计时器和目标/ Action 模式。 Swift 提供 Selector使用这些类型。 (Swift 自动使用它来代替 ObjC 的 SEL 类型。)
    在 Swift 2.2 (Xcode 7.3) 及更高版本(包括 Swift 3/Xcode 8 和 Swift 4/Xcode 9)中:
    您可以构建一个 Selector从 Swift 函数类型使用 #selector表达。

    let timer = Timer(timeInterval: 1, target: object,
    selector: #selector(MyClass.test),
    userInfo: nil, repeats: false)
    button.addTarget(object, action: #selector(MyClass.buttonTapped),
    for: .touchUpInside)
    view.perform(#selector(UIView.insertSubview(_:aboveSubview:)),
    with: button, with: otherButton)
    这种方法的好处是什么? Swift 编译器会检查函数引用,因此您可以使用 #selector仅使用实际存在并有资格用作选择器的类/方法对的表达式(请参阅下面的“选择器可用性”)。您还可以根据 the Swift 2.2+ rules for function-type naming 自由地将您的函数引用设置为您需要的那样具体。 .
    (这实际上是对 ObjC 的 @selector() 指令的改进,因为编译器的 -Wundeclared-selector 检查仅验证命名选择器是否存在。传递给 #selector 的 Swift 函数引用检查存在性、类中的成员资格和类型签名。 )
    对于传递给 #selector 的函数引用,还有一些额外的注意事项。表达:
  • 使用上述 syntax for function references 可以通过参数标签区分具有相同基本名称的多个函数(例如 insertSubview(_:at:)insertSubview(_:aboveSubview:) )。但是如果一个函数没有参数,消除歧义的唯一方法是使用 as使用函数的类型签名进行强制转换(例如 foo as () -> ()foo(_:) )。
  • Swift 3.0+ 中的属性 getter/setter 对有一个特殊的语法。例如,给定 var foo: Int , 你可以使用 #selector(getter: MyClass.foo)#selector(setter: MyClass.foo) .

  • 一般注意事项:
    案例#selector不起作用,命名:有时您没有函数引用来创建选择器(例如,使用在 ObjC 运行时中动态注册的方法)。在这种情况下,您可以构造一个 Selector来自一个字符串:例如 Selector("dynamicMethod:") —尽管您丢失了编译器的有效性检查。当您这样做时,您需要遵循 ObjC 命名规则,包括每个参数的冒号 ( :)。
    选择器可用性:选择器引用的方法必须暴露给 ObjC 运行时。在 Swift 4 中,暴露给 ObjC 的每个方法的声明都必须以 @objc 开头。属性。 (在以前的版本中,在某些情况下您可以免费获得该属性,但现在您必须显式声明它。)
    请记住 private符号也不会暴露给运行时——你的方法至少需要有 internal能见度。
    关键路径:这些与选择器相关但不完全相同。在 Swift 3 中也有一种特殊的语法:例如 chris.valueForKeyPath(#keyPath(Person.friends.firstName)) .见 SE-0062详情。还有更多 KeyPath stuff in Swift 4 ,因此请确保您使用正确的基于 KeyPath 的 API 而不是选择器(如果合适)。
    您可以在 Interacting with Objective-C APIs 下阅读有关选择器的更多信息。在将 Swift 与 Cocoa 和 Objective-C 结合使用。
    注:在 Swift 2.2 之前, Selector符合 StringLiteralConvertible ,因此您可能会发现旧代码将裸字符串传递给采用选择器的 API。您需要在 Xcode 中运行“转换为当前 Swift 语法”以获取使用 #selector 的用户。 .

    关于swift - Swift 中的@selector()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36163271/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com