文章目录

  • 前言
  • 使用示例
    • 一般闭包示例
    • Delegated 示例
  • 源码解析
  • 示例Demo
    • 示例Demo地址

前言

在Swift中我们使用闭包(Callback)的时候经常要写 [weak self] or [unowned self].
而且你不写, 系统也不会提示你, 这就很容易出现循环引用. ( /(ㄒoㄒ)/~~ 表示本人已经忘记无数次了. )
所以为了避免这种情况, 自然而然就有了这个库 Delegated .

使用示例

一般闭包示例

// 声明
typealias XQCallback = (String) -> ()
private var callback: XQCallback?
// 调用闭包
callback(str)// 外部给闭包赋值
self.callback { [unowned self] (value) inprint(self, value)
}

Delegated 示例

// 声明, 并创建结构体  <inputValue, outputValue>
// inputValue: 调用闭包传出去的值
// outputValue: 闭包内return出来的值
var callback = Delegated<String, Void>.init()
// 调用闭包
callback.call("inputValue")// 外部给闭包赋值
callback.delegate(to: self) { (self, inputValue) inprint(self, inputValue)
}

使用起来, 和原来的闭包写的差不多, 但是这边是把 self 作为参数传进去, 避免了忘写的尴尬.

源码解析

整个库就一个文件, 而且代码很少, 我们一个一个方法来解析.

public struct Delegated<Input, Output> {// 赋值闭包, 无需自己写weak// !!!这个是主要方法, 看明白这个就可以了public mutating func delegate<Target : AnyObject>(to target: Target,with callback: @escaping (Target, Input) -> Output) {// 赋值callback, 并且weak传入的target值 (这里就把原本我们要写的weak做了)self.callback = { [weak target] input inguard let target = target else {return nil}return callback(target, input)}}// 调用callbackpublic func call(_ input: Input) -> Output? {return self.callback?(input)}// 声明闭包private(set) var callback: ((Input) -> Output?)?// 是否已经赋值callback true已赋值, false未赋值public var isDelegateSet: Bool {return callback != nil}public init() { }}// 这个扩展用到了一个 where Output == Void, 很巧妙.
// 这样的话, 传入output是Void类型, 调用闭包时, 就会自动为无返回值.
extension Delegated where Output == Void {// 调用闭包public func call(_ input: Input) {self.callback?(input)}
}// 这个扩展不需要看太多, 我大致标明一下函数含义就行
extension Delegated {// 赋值闭包, 需要自己写weakpublic mutating func stronglyDelegate<Target : AnyObject>(to target: Target,with callback: @escaping (Target, Input) -> Output) {}// 赋值闭包, 需要自己写weakpublic mutating func manuallyDelegate(with callback: @escaping (Input) -> Output) {}// 删除当前已赋值的闭包public mutating func removeDelegate() {}
}

虽然代码量少, 但是这个思路真的不错, 胜在实用性.
不过这个第三方还有几个点没解决

  • 没提供能动态多个weakTarget
  • input只有一个参数.

不过这都是小事,明白原理之后, weakTarget可以自己照着写, 多写几个就行.(应该也不会用很多个吧 ✧(≖ ◡ ≖) )
而参数问题, 我们可以不写多几个函数, 我们可以直接用元组, 如下:

 // typealias 一个元组类型typealias Login = (acc: String, pwd: String)// Delegated 声明并初始化var callback = Delegated<Login, Void>.init()// 点击登录按钮@IBAction func respondsToBtn(_ sender: Any) {// Delegated 调用闭包self.callback.call(("账号", "密码"))}// 外部赋值闭包self.tView.callback.delegate(to: self) { (self, info) inprint("acc:", info.acc, "\npwd:", info.pwd)}

这样一个参数也无所谓了

示例Demo

写了一个使用示例demo, 两个页面的跳转, 按钮的点击是一个view传到viewController.
展示了普通闭包和使用Delegated的区别

使用普通闭包回跳.
真的容易忘写 /(ㄒoㄒ)/~~ ,自从写Swift以来, 不知道忘写多少次了.

使用Delegated回跳

示例Demo地址

DelegatedDemo

解决Swift中callback循环引用 - Delegated(Library)相关推荐

  1. 【FastJSON】解决FastJson中“$ref 循环引用”的问题

    0.开发环境 SSH,EasyUI,MySQL 1.需求要求: (1)首先获取所有的贷款订单数据,即List <LoanOrder>. (2)然后从单个贷款订单实体LoanOrder去访问 ...

  2. 解决FastJson中“$ref 循环引用检测”的问题的几种方式

    一.现象: 项目中用json形式来存储一个集合对象,用fastjson发现多了一些东西:$ref,了解之后才发现是重复引用的问题. [{"id":"1",&qu ...

  3. Swift之常见闭包与defer关键字的使用分析和闭包中的循环引用 | CSDN创作打卡

    一.什么是闭包? 在 Swift 中,可以通过 func 定义一个函数,也可以通过闭包表达式定义一个函数,闭包是一个捕获了上下文的常量或者是变量的函数.闭包(Closures)是自包含的功能代码块,可 ...

  4. Javascript 深度克隆中的循环引用问题解决和代码优化

    概要 在前端项目开发中,我们经常需要深度克隆JS对象.在克隆代码开发过程中,我们经常会遇到数组判定或对象循环引用的问题. 本文通过实例来解决上述问题 代码及实现 常见深度克隆JS对象的代码 funct ...

  5. 小记 TypeScript 中的循环引用问题

    随着项目规模的不断增长,循环引用问题似乎总是不可避免,本文就 TypeScript 中可能出现的循环引用问题做了一些简单记录~ 平时编写 TypeScript 代码时,一般都倾向于使用模块(Modul ...

  6. 深入理解C++中的循环引用问题及解决方法

    循环引用问题在C++中是指当两个或多个对象互相持有对方的引用(通常是通过智能指针),导致它们的引用计数永远不会降为零,从而导致内存泄漏的情况.这种问题在使用shared_ptr时尤为突出,因为shar ...

  7. nstimer循环引用_ios开发中经典循环引用场景?

    1.属性传值循环引用 如:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexP ...

  8. 聊一聊 JS 中的循环引用及问题

    本文主要从 JS 中为什么会出现循环引用,垃圾回收策略中引用计数为什么有很大的问题,以及循环引用时的对象在使用 JSON.stringify 时为什么会报错,怎样解决这个问题简单谈谈自己的一些理解. ...

  9. 解决Swift中present(uiImagePickerController,animated: true,completion: nil)闪退的问题

    swift中开发选择图片上传,会使用到Tap Gesture Recognizer控件,对应 UITapGestureRecognizer API,以下是代码示例(取自IOS developer li ...

最新文章

  1. 【图论】【二叉树】以先序字符串方式建立二叉树
  2. oracle status
  3. 科学家用大脑控制平板电脑操作 真的可以!
  4. Part5核心初始化_lesson3---关闭看门狗
  5. P6砖家:对不起,我没.NET5高并发经验,我要跑路了!
  6. spring boot入门(九) springboot的过滤器filter。最完整、简单易懂、详细的spring boot教程。
  7. 关于linux拨号上网的软件实现方案[原创]
  8. 软件工程 选课系统的uml类图_想成为高级程序猿,面向对象建模和UML你不应该知道?...
  9. xutil3网络框架
  10. meshlab模型简化
  11. Linux 之六 Shell、终端(Terminal)、控制台(Console)、CLI 命令行界面、GUI 图形用户界面(X、X11、Xfree86、Xorg、GNOME、KDE)
  12. 【3dmax千千问】初学3dmax插件神器第17课|VRAY渲染教程|哪三种表现方式最能影响3dmax疯狂模渲大师设计效果图的写实程度?食住玩3dmax入门到精通进阶教程
  13. RTL8152网卡灯配置详细说明
  14. python进行邮件文件.eml.pst.msg信息提取(包括附件)
  15. 微信小程序:map组件的简单使用,标注callout与label简单用法
  16. Dharma勒索病毒变种 ---加密后文件后缀.bkpx
  17. 原生Android打造一个炫酷的底部导航栏
  18. 量子计算机有生之年,对话哈佛大学教授Lukin:量子计算将在我们有生之年普及!...
  19. 纯干货!信贷行业电话销售员一定要掌握的电话沟通话术
  20. 红烧茄条————————炒茄子不费油却很好吃的办法

热门文章

  1. 家用宽带如何接入所有的房间,只需要电脑和一段网线自己就可以完成
  2. python爬虫论坛1688_Python爬虫抓取论坛关键字过程解析
  3. java初级ppt笔记
  4. php获取空间头像图片的方法
  5. 微信机器人红包java_安卓微信HOOK,自动好友,自动聊天,自动抢红包,机器人
  6. Python爬虫爬取新浪新闻内容
  7. 【微信小程序】【智能春联】春节 “迎春对联” 微信小程序 丨 2022
  8. php x4co 16进制,北语18春《PHP》作业1234参考
  9. jQuery——插件
  10. 6个月的测试经验,来面试居然开口要17K,面试完,我5K都不想给他.....