Swift 语言多播委托

2023-11-24

我正在尝试在 Swift 中实现多播委托功能。在 Objective C 中,我们有这个优秀的实现

https://github.com/robbiehanson/XMPPFramework/blob/master/Utilities/GCDMulticastDelegate.m

我刚刚创建了这个基本功能:

protocol MyProtocol : class{
    func testString()-> String;
}

class MulticastDelegateNode <T:AnyObject> {
    weak var delegate : T?

    init(object : T){
        self.delegate = object;
    }
}

class MulticastDelegate <T:AnyObject> {
    var delegates = Array<MulticastDelegateNode<T>>()


    func addDelegate(delegate : T){
        var newNode = MulticastDelegateNode(object : delegate);
        delegates.append(newNode);
    }

    func removeDelegate(delegate : AnyObject){
        self.delegates = self.delegates.filter({ (node : MulticastDelegateNode) -> Bool in
            return node.delegate !== delegate;
        });
    }
}

class OP {
    var delegate  = MulticastDelegate<MyProtocol>();

    func process(){
        //...
        //make actions

        //notify the objects!
    }

}

我的问题是,我似乎无法找到一种方法来做到这一点:

delegate.testString()

为了向节点中的所有委托提供命令“testString()”。谁能帮我这个?


Swift 3执行:

class MulticastDelegate<T> {
    private var delegates = [Weak]()

    func add(_ delegate: T) {
        if Mirror(reflecting: delegate).subjectType is AnyClass {
            delegates.append(Weak(value: delegate as AnyObject))
        } else {
            fatalError("MulticastDelegate does not support value types")
        }
    }

    func remove(_ delegate: T) {
        if type(of: delegate).self is AnyClass {
            delegates.remove(Weak(value: delegate as AnyObject))
        }
    }

    func invoke(_ invocation: (T) -> ()) {
        for (index, delegate) in delegates.enumerated() {
            if let delegate = delegate.value {
                invocation(delegate as! T)
            } else {
                delegates.remove(at: index)
            }
        }
    }
}

private class Weak: Equatable {
    weak var value: AnyObject?

    init(value: AnyObject) {
        self.value = value
    }
}

private func ==(lhs: Weak, rhs: Weak) -> Bool {
    return lhs.value === rhs.value
}

extension RangeReplaceableCollection where Iterator.Element : Equatable {
    @discardableResult
    mutating func remove(_ element : Iterator.Element) -> Iterator.Element? {
        if let index = self.index(of: element) {
            return self.remove(at: index)
        }
        return nil
    }
}

您可以使用以下方法进行测试:

protocol SomeDelegate: class {
    func onSomeEvent()
}

class SomeDelegateImpl: SomeDelegate {
    let value: Int

    init(value: Int) {
        self.value = value
    }

    func onSomeEvent() {
        print("Invoking delegate \(value)")
    }
}

let multicastDelegate = MulticastDelegate<SomeDelegate>()

func testInvoke() {
    multicastDelegate.invoke {
        $0.onSomeEvent()
    }
}

print("Adding first delegate.")

let delegate1 = SomeDelegateImpl(value: 1)

multicastDelegate.add(delegate1)

testInvoke()

let delegate2 = SomeDelegateImpl(value: 2)

print("Adding second delegate.")

multicastDelegate.add(delegate2)

testInvoke()

print("Removing first delegate.")
multicastDelegate.remove(delegate1)

testInvoke()

print("Adding third delegate.")

({
    let delegate3 = SomeDelegateImpl(value: 3)
    multicastDelegate.add(delegate3)
    testInvoke()
})()

print("Third delegate is deallocated by ARC.")

testInvoke()

它打印:

Adding first delegate.
Invoking delegate 1.
Adding second delegate.
Invoking delegate 1.
Invoking delegate 2.
Removing first delegate.
Invoking delegate 2.
Adding third delegate.
Invoking delegate 2.
Invoking delegate 3.
Third delegate is deallocated by ARC.
Invoking delegate 2.

基于这篇博文.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift 语言多播委托 的相关文章

  • iOS 在视图中添加/删除阴影

    我不明白如何删除添加到视图中的阴影 我添加到我的视图中initWithFrame这样的阴影 self layer borderWidth 2 self layer borderColor UIColor clearColor CGColor
  • UIView表面自定义变换/动画(如“水滴效果”)

    实施方式是什么自定义转换 动画 在视图表面 类似于所附图片 not只是视图边界 问题主要在于一般的方法是什么做到这一点 不完全是 水滴效应 但任何例子肯定会受到赞赏 我想 这是层布局 网格 的某种 算法 转换 但不确定以哪种方式 挖掘 它
  • 具有函数的 NSSortDescriptor

    我在使用 NSSortDescriptor 方面的经验有限 它可以通过一键进行排序 而且效果很好 但这是我现在需要的 我有一组数字对 例如 2 3 44 5 6 17 33 7 173 21 我想根据给定函数 myfunction x y
  • 如何更改 iOS 5 中 UITabBarItem 中文本的颜色

    iOS 5 中有更多外观控制 我们如何更改 UITabBarItem 文本颜色 从默认白色变为其他颜色 编辑 工作解决方案 UITabBarItem appearance setTitleTextAttributes NSDictionar
  • 应用程序关闭时下载报刊亭应用程序

    我正在实现一个报摊杂志应用程序 它通过 Urban Airship 推送通知接收新期刊 只要应用程序位于前台或后台 这就可以正常工作 但据我所知 当应用程序完全关闭时也应该触发下载 但发送推送 content available 1如果我的
  • 如何在 Swift Joint 中创建自定义链?

    我正在尝试创建一个LocationManager组合的包装 我有一个发布者和一些触发发布者的函数 但是 我想将它们与自定义命令组合在一起 这是我到目前为止得到的 available OSX 10 15 iOS 13 tvOS 13 watc
  • 如何正确设置UIView的alpha? [iOS]

    I have UIView有很多子视图 UILabel UITextView 等 如果为主视图设置 alpha 0 6 则所有子视图均采用此 alpha 如何单独设置主视图的alpha view setBackgroundColor UIC
  • Swift Animate 持续时间在 CGAffineTransform 中不起作用

    当我用 1 秒的动画翻译一个视图时 它不起作用 但当我执行 transform identity 时 它工作正常 这是我的代码 func hideCarousel UIView animate withDuration 1 animatio
  • 预填充 UICollectionView 单元重用队列

    问题 我有一个应用程序 只有一个UICollectionView我第一次滚动它时很卡顿 我已将来源范围缩小到正在创建新单元格 2 的事实 使用initWithFrame 因为周围没有可以重复使用的细胞 初始滚动后 重用队列不为空 单元格可以
  • UIBarButtonItem 按下后更改字体,在外观代理中指定

    我设置了UIBarButtonItem标题字体通过appearanceAppDelegate 中的代理 UIBarButtonItem appearance setTitleTextAttributes NSDictionary dicti
  • 在 swift ios 中播放远程 mp3 文件需要花费大量时间

    我有麻烦了 我想在我的应用程序中播放远程 mp3 文件 但 mp3 文件需要很长时间 大约 5 6 分钟 来播放 为什么 任何人都可以建议我应该做什么 import UIKit import AVFoundation class TestV
  • 应用程序:didReceiveRemoteNotification:未调用 fetchCompletionHandler

    出现了这个功能application didReceiveRemoteNotification fetchCompletionHandler当应用程序被强制退出时不会被调用 我的印象是 无论应用程序处于什么状态 该函数都会被调用 但似乎只有
  • 适用于 iOS 的 MvvmCross 汉堡菜单

    我在用着https www marcbruins nl xamarin ios hamburger menu mvvmcross https www marcbruins nl xamarin ios hamburger menu mvvm
  • 如何处理 iPhone 6S Plus 字体大小?

    与其他屏幕尺寸相比 iPhone 6S Plus 的屏幕非常大 我似乎无法找到一种在不以编程方式调整大小的情况下处理标签字体大小的好方法 如何调整标签的字体大小 使其在 iPhone 5 上看起来更小 在 iPhone 6 Plus 上看起
  • 在 iOS 中,如何以编程方式填写 pdf 表单字段?

    我需要获取一个现有的 pdf 文件 并以编程方式填写带有文本的表单字段列表 然后保存 pdf 而不将其显示给用户 例如 如果 pdf 文件包含名为 LastName 和 FirstName 的字段 我想将 FirstName 的值设置为 L
  • Swift 上的 USB 连接委托

    Swift 中是否有一个代表可以让我的班级知道何时通过计算机的 USB 插入新设备 我想知道我的程序何时可以使用新设备 Eric Aya 的答案已经相当不错了 但这里有一个 Swift 3 的改编 我把大部分丑陋的东西包裹在一个USBWat
  • 如何从TableViewCell上的自定义CollectionViewCell推送VC?

    我有一个tableView和细胞 在细胞上我有一个collectionView并在其上显示一些内容 我想发送一个有关选择的链接indexPath 我想从自定义中推送 呈现我的视图CollectionViewCell这是在TableViewC
  • 将 MPMoviePlayerController 的视图添加到 UIView

    我想添加MPMoviePlayerController to a UIView 首先 我在 xib 文件中放置了一个视图 名为 youTubeView youtube播放器是MPMoviePlayerController youtubePl
  • 根据 Swift 中的列表选择在 ViewController 之间传递值

    我试图将 listView 选择的选定索引号从一个 ViewController 传递到另一个 ViewController 但遇到了 tableView didSelectRowAtIndexPath 委托运行时间稍晚于prepareFo
  • iOS 上 Safari 中的 shift 键

    有没有办法在javascript中判断手机键盘上是否按下了shift键 并将其与大写锁定 按两次shift键 区分开来 一些事实 首先 让我们看一下有关 iOS 键盘的一些事实 我假设您已经知道了 当您进入键盘模式时 shift键始终处于激

随机推荐

  • Google Places API 类型功能..

  • 如何使用 PDO 在 MySQL 中存储 BIGINT?

    我知道这个问题在这里被问过不止一次 但我找不到解决方案 我们正在使用一个数据库 将 facebook id 存储为 BIGINT 20 create table users fb id bigint 20 NOT NULL user nam
  • 如何更新绘图表达树形图以同时具有标签和绘图内的值?

    目前 plotly express 树形图仅显示树形图中的标签 如何在标签旁边包含该值 这就是为什么我不喜欢 Express 它有太多限制 要进行这些更改 您必须以任何一种方式访问 跟踪 从我的角度来看 使用普通的绘图更好 代码更透明 话虽
  • 如何在 Delphi XE 应用程序中使用 CHM HTML 帮助文件?

    Delphi 如何在 Delphi XE 应用程序中使用 CHM HTML 帮助文件 http edn embarcadero com article 27842文章介绍了如何使用 CHM 文件 我执行了那里描述的所有步骤 Added co
  • 如何更改 Android WebView 中的 FontSize?

    如何手动更改网页视图的字体大小 例如当页面在 web 视图中加载时 字体大小约为 24pt 对于我的安卓屏幕来说太大了 我查看了 网络设置 但似乎两者不相关 Thanks 我终于找到了 WebSettings webSettings web
  • 反斜杠 - 正则表达式 - Javascript

    我想构建一个 JS 函数 将参数列表连接到有效路径 因为我无法确定路径的一部分是否带有斜杠 这是函数 concatPath function var path for var i 0 i lt arguments length i path
  • 使用 Pear Mail 发送邮件的 PHP 脚本有什么问题?

    我有这个脚本 require once Mail php from Stephen lt email protected gt Google apps domain to email protected subject Hi body Hi
  • API网关CORS问题

    因此 我通过 AWS Gateway 提供的基本设置启用了 CORS 然而 对于这个 API 我需要允许所有请求的控制源并允许凭据 这是它的样子 您可能已经猜到的问题是 CORS 不允许此设置 您不能使用 Origin 通配符并将凭据设置为
  • 如何从代码隐藏中清除所有表单字段?

    HTML 有一种输入按钮类型 可以一步将表单中的所有字段重置为其初始状态
  • 如何使用JPA删除连接表中的行

    我有以下模型 一篇文章可以有一些标签 并且一些文章上可以有一个标签 所以它是与 3 个表的多对多关系 ARTICLE ARTICLE TAG TAG 当我删除标签时 我想删除 TAG 中的标签 该标签与 ARTICLE TAG 中标记的文章
  • 删除 DialogFragment 的正确方法:dismiss() 或 transaction.remove()?

    由于以下原因 我仍然遇到问题DialogFragment用于我的主要活动 我目前正在使用此代码来删除它 FragmentTransaction transaction getFragmentManager beginTransaction
  • 如何在 python 中使用 imaplib 获取电子邮件正文?

    我想从 IMAP4 服务器获取整个邮件 在 python 文档中 如果发现这段代码有效 gt gt gt t data M fetch 1 RFC822 gt gt gt body data 0 1 我想知道我是否始终可以相信 data 0
  • 如何在 Java 5 中屏蔽密码?

    我正在尝试用 Java 屏蔽密码 Sun java 建议了一种屏蔽密码的方法 如下所示 屏蔽密码 它使用一种简单的方法来做到这一点 public void run stop true while stop System out print
  • 使用自定义 AuthorizeAttribute 生成返回 URL

    我有一个自定义授权属性 using System using System Web Mvc using System Web Routing AttributeUsage AttributeTargets Class AttributeTa
  • 预取示例?

    任何人都可以给出一个示例或使用示例的链接 builtin prefetch在 GCC 或一般的 asm 指令 prefetcht0 中获得显着的性能优势 特别是 我希望该示例满足以下标准 这是一个简单 小型 独立的示例 删除 builtin
  • 角度/打字稿中的顺序代码执行

    如何让我的代码按顺序运行 例如 如果我有一个从服务获取一些数据的 for 循环 我想要n 1迭代仅在之后运行nth迭代已完成 我希望循环后的代码仅在 for 循环完成所有交互后才执行 示例代码 someMethod for var i 0
  • ChartJS 显示时间数据的差距

    我有这个图表 这是用 ChartJS 构建的 但是 在下午 1 点到 5 30 之间 没有数据 我想要图表做的就是显示没有数据 而不是连接两个点 这可以做到吗 理论上 我每 5 秒就有一个新值 但这可能会减少 所以我想我需要能够设置连接间隙
  • 如何在 sqlite.net PCL 中使用 InsertOrReplace?

    我正在使用这里的 sqlite net 的 PCL 版本 https github com oysteinkrog SQLite Net PCL 这是我的简单课程 public class LogEntry PrimaryKey AutoI
  • 非阻塞 API 是如何工作的?

    我一直在读Play 框架文档并发现这句话令人困惑 请注意 您可能会因此将阻塞代码包装在 期货 这并不意味着它是非阻塞的 它只是意味着 阻塞将发生在不同的线程中 你还需要做 确保您使用的线程池有足够的线程 处理阻塞 我的印象是所有这些非阻塞库
  • Swift 语言多播委托

    我正在尝试在 Swift 中实现多播委托功能 在 Objective C 中 我们有这个优秀的实现 https github com robbiehanson XMPPFramework blob master Utilities GCDM