如何在协议扩展中使用#selector(myMethodName)?

2023-12-26

protocol LazyUpdateable {
    func waitToDoStuff()
    func myMethodName()
}


extension LazyUpdateable where Self: NSObject {
    func waitToDoStuff() {
        self.performSelector(#selector(myMethodName), withObject: nil, afterDelay: 1.5)
    }

    func myMethodName() {

    }
}

通过此更新,我收到错误Argument of #selector refers to a method that is not exposed to objective c,但如果我选择旧的Selector("myMethodName")我收到警告,要求我改用更好的方法。是否可以使用#selector()在这种情况下?它不会与设置一起使用@objc根据我的协议,我已经尝试过了。

这是一个你可以尝试的游乐场,它显示它不适用于设置@objc

import Foundation
import UIKit
import XCPlayground


@objc protocol LazyUpdatable {
    optional func waitToDoStuff()
    optional func myMethodName()
}

extension LazyUpdatable where Self: UIViewController {
    func waitToDoStuff() {
        self.performSelector(#selector(myMethodName), withObject: nil, afterDelay: 1.5)
    }

    func myMethodName() {
        print("LOL")
    }
}


@objc
class AViewController: UIViewController, LazyUpdatable {
    func start() {
        waitToDoStuff()
    }
}

let aViewController = AViewController()
aViewController.start()

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

使用 #selector() 或 Selector() 的动态调度看不到您的 Swift 协议扩展。相反,如果可能的话,尝试完全避免 Objective-C。您可以使用 libdispatch 获得相同的结果:

protocol LazyUpdatable {

    func waitToDoStuff()
    func myMethodName()
}

extension LazyUpdatable {

    func waitToDoStuff() {
        let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1.5 * Double(NSEC_PER_SEC)))
        dispatch_after(dispatchTime, dispatch_get_main_queue()) {
            self.myMethodName()
        }
    }

    func myMethodName() {
        print("Aloha!")
    }
}

class ViewController: UIViewController, LazyUpdatable {

    override func viewDidLoad() {
        super.viewDidLoad()
        waitToDoStuff()
    }
}

当然,这不像使用选择器那么灵活,但可以让您使用真正的 Swift 协议扩展。

EDIT:如果您希望能够取消调用方法调用,请尝试以下操作:

var lazyUpdatableCancelKey = UInt8(0)

protocol LazyUpdatable: class {

    func waitToDoStuff()
    func cancelDoingStuff()
    func myMethodName()
}

extension LazyUpdatable {

    func waitToDoStuff() {
        let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1.5 * Double(NSEC_PER_SEC)))
        dispatch_after(dispatchTime, dispatch_get_main_queue()) {
            if let shouldCancel = objc_getAssociatedObject(self, &lazyUpdatableCancelKey) as? Bool where shouldCancel == true {
                return
            }
            self.myMethodName()
        }
    }

    func cancelDoingStuff() {
        objc_setAssociatedObject(self, &lazyUpdatableCancelKey, true, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }

    func myMethodName() {
        print("Aloha!")
    }
}

class ViewController: UIViewController, LazyUpdatable {

    override func viewDidLoad() {
        super.viewDidLoad()
        waitToDoStuff()

        let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1.4 * Double(NSEC_PER_SEC)))
        dispatch_after(dispatchTime, dispatch_get_main_queue()) {
            self.cancelDoingStuff()
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在协议扩展中使用#selector(myMethodName)? 的相关文章

随机推荐

  • Kubernetes 服务到底是什么以及它们与部署有何不同

    在阅读了这样的 Kubernetes 文档后 部署 https kubernetes io docs concepts workloads controllers deployment service https kubernetes io
  • 检查渲染方法

    我正在使用react redux 和react redux router 当我运行应用程序时 出现错误 我不明白它与我的 App js 中的 React 渲染函数有什么关系 在我看来 问题出在代码的其他地方 错误如下 Warning Rea
  • 如何在“map”对象中编写 OpenAPI 3 (Swagger) 规范的属性名称?

    我试图描述的 API 具有一个结构 其中根对象可以包含任意数量的子对象 属性本身就是对象 根对象中的 键 或属性是子对象的唯一标识符 值是子对象的其余数据 child1 bunch of stuff child2 bunch of stuf
  • Oracle 的 C# 参数化查询 - 严重且危险的错误!

    这绝对是一个嚎叫 我不敢相信自己的眼睛 而且我不敢相信 如果这是 C 中的一个真正的错误 那么在我之前没有人会发现这一点 所以我将其发布给开发人员社区的其他成员 让他们告诉我我做错了什么 我确信这个问题会让我说 DOH 然后用手掌用力拍打我
  • 将列中的任意字符串替换为 1

    我正在和熊猫一起工作 我的目标是将数据帧中包含 NaN 或字符串数 据的几列转换为或多或少的虚拟变量 0 代表 NaN 1 代表任何字符串 我想在不使用完整的字符串列表并替换它们的情况下执行此操作 因为存在拼写错误 这会导致错误 我已经能够
  • 通过 api.linkedin.com/v2/shares 检索共享时排序不正确

    根据文档 https learn microsoft com en us linkedin marketing integrations community management shares share api retrieve shar
  • DPDK RX/TX 回调示例应用程序中没有流量出现

    我是DPDK领域的新生 我从 DPDK 主页给出的示例应用程序开始 我被这个例子困住了 DPDK RX TX 回调示例应用程序 https doc dpdk org guides sample app ug rxtx callbacks h
  • Android检测webview URL变化

    我的 android 应用程序中有一个 webview 希望检测 url 何时发生变化 我想用它来当用户位于 info php 页面上时隐藏顶部栏中的信息按钮 并在用户不在 info php 页面上时再次显示该按钮 我用谷歌搜索但找不到任何
  • 如何将数组数据从javascript发送到flask

    如何将数组从 javascript 发送到 python Flask ajax 没有将数组 值 返回到 Flask 路由 任何人都可以帮助解决这些错误 flask route app route admin methods POST GET
  • 将 PHP 5.3 匿名函数转换为 5.2 兼容函数

    我在另一个函数中有这个匿名函数 build tree 它在 PHP 5 3 中运行良好 function nest list list index array index nodes list index build tree functi
  • Git Stash 的新分支会影响其他存储吗?

    我在主分支上存储了多个更改 现在我想从位于 0 的存储更改创建一个新分支 但我怀疑新分支的创建不会影响我的其他存储 因为git创建新分支后会丢弃我的藏品 将要git只删除 0 索引处的存储 还是会删除所有存储 隐藏的更改对我来说太重要了 简
  • PC寄存器上的ARM LDR指令

    我是这样理解这个故事的 PC寄存器保存指向下一条指令的指针 LDR指令正在将第二个操作数的值加载到第一个操作数中 例如 LDR r0 pc 0x5678 相当于这个 C代码 r0 pc 0x5678 它是带有基址偏移量的指针解引用 我的问题
  • 如何测试MySQL查询速度,同时减少不一致?

    我需要一种简单的方法来测试 SQL 查询的速度 我不担心硬件差异 我基本上需要一个相对数字 这就是我一直在用 PHP 做的事情 它很模糊 但有效 CONNECT TO DB HERE sub new YomoSubscription 95
  • 为什么我们使用输入隐藏权重矩阵而不是隐藏输出权重矩阵作为词向量?

    在word2vec中 经过训练 我们得到两个权重矩阵 1 输入隐藏权重矩阵 2 隐藏输出权重矩阵 人们会使用输入隐藏权重矩阵作为词向量 每一行对应一个词 即词向量 这是我的困惑 为什么人们使用输入隐藏权重矩阵而不是隐藏输出权重矩阵作为词向量
  • 错误:类型“数字”无法分配给类型“十进制”

    我想手动创建 Prisma 架构的对象 const order Order id 1 name Name price 99 Somewhere in autogenerated file by Prisma export type Orde
  • RecyclerView - 如何获取每行视图的引用

    我正在使用新的RecyclerView取代我现有的ListViews并遇到了以下问题 在旧的BaseAdapter 我可以创建一个 飞入 Animation对于适配器内的每个项目 只需应用此Animation to the convertV
  • 为什么帐户模块升级会取消某些表上的记录链接?

    我只是想确保升级base or account模块一切正常 因为如果我对模块进行新的更改 我想将来升级数据库 我已在模型上手动创建新记录account acount type 但是当我尝试升级时account模块中 出现了写在这个问题底部的
  • 使用 Expect 自动执行 2 个脚本之间的交互

    我有两个简单的脚本 我需要它们使用第三个脚本自动相互交互expect script script1 sh bin bash echo s1 started echo question1 read echo got REPLY echo qu
  • 客户端不支持服务器请求的身份验证协议

    我需要建立PHP4环境结合mysql5 当我尝试连接mysql时遇到这个问题 谢谢你的任何踪迹 The solution http chrisjean com 2010 05 25 fix php 4 client does not sup
  • 如何在协议扩展中使用#selector(myMethodName)?

    protocol LazyUpdateable func waitToDoStuff func myMethodName extension LazyUpdateable where Self NSObject func waitToDoS