Swift 和OC的blcok属性不一致问题

组件之间进行属性传值的时候,如果通过CTMediator来进行block传值,swift和OC间就会出现block的传值类型不一致,导致报错问题。
这里我们可以利用convention 字段来进行相关转换

此特性用于修饰一个函数对象的类型,以指 定其调用约定。Swift一共有三种调用约定:

(1)swift:用于指示该函数对象为一个 Swift函数的引用。这也是Swift编程语言的标准 函数调用约定。

(2)block:用于指示该函数对象与 Objective-C的Block引用相兼容。也就是说,它 是一个与Objective-C中的 id 相兼容的Objective-C对象,该Block对象将其函数调用嵌 入在其对象内。而内部的函数调用则用的是C调用约定。

(3)c:用于指示该函数对象是一个C函数 的引用。也就是说,该函数引用不带任何执行 上下文,并且直接使用C语言函数调用约定。这 意味着此函数对象可以与C语言中的函数指针进 行直接交互。我们在第22章中会做详细介绍。

我们下面来看些简单的例子。

func test() {
    var x = 100
/// ref1具有Swift标准函数调用约定,
/// 它可以对一个捕获局部对象的闭包进行引用 let ref1: @convention(swift) (Int) ->
Void = {
        (a: Int) -> Void in
x += a }
/// ref2具有block调用约定,
/// 它可以直接与Objective-C中的Block进行交 互,
/// 同时也能作为一个Objective-C的对象进行使用
    let ref2: @convention(block) (Int) ->
Void = {
        (a: Int) -> Void in
x -= a }
/// ref3具有C函数调用约定,
/// ref3不能引用一个捕获局部对象的闭包,
/// 因为普通的C函数没有自己的执行上下文,
/// 因此无法对局部对象的捕获做任何处理
let ref3: @convention(c) (Int) -> Void =
    ref1(10)
    ref2(5)
    ref3(1)
    print("x = \(x)")
}
test()

ok,convention字段介绍完了,我们这里就用到了它的block调用约定

  /*
         1、 拿到OC传过来的 block 属性
         */
        let parBlock = params["block"]
        
        /*
         2、 定义对应类型的 block 别名,用 @convention(block) 修饰
         @convention(swift) block类型 :声明这是swift block
         @convention(block) block类型 :声明这是兼容swift | oc 的 block
         @convention(c)     block类型 :声明这是c block
     
         BlockType       : 别名
         ((Dictionary<String,Any>) -> Void : 传入swift中的 block 类型
         */
        typealias BlockType = @convention(block) (Dictionary<String,Any>) -> Void
     
        /*
         3、 获取 parBlock 的内存地址
         Unmanaged: 用于传播非托管对象引用的类型(不用ARC)
         Unmanaged.passRetained       : 如果这个非托管对象的使用全程,能够保障被封装对象一直存活,我们就可以使用 passUnretained 方法,对象的生命周期还归编译器管理
         Unmanaged.passUnretained     : 如果非托管对象使用周期超过了编译器认为的生命周期,比如超出作用域,编译器自动插入 release 的 ARC 语义,那么这个非托管对象就是一个野指针了,此时我们必须手动 retain 这个对象,也就是使用 passRetained 方法
         一旦你手动 retain 了一个对象,就不要忘记 release 掉它,方法就是调用非托管对象的 release 方法,或者用 takeRetainedValue 取出封装的对象,并将其管理权交回 ARC。但注意,一定不要对一个用 passUnretained 构造的非托管对象调用 release 或者 takeRetainedValue,这会导致原来的对象被 release 掉,从而引发异常。
        */
        let blockPtr = UnsafeRawPointer(Unmanaged<AnyObject>.passUnretained(parBlock as AnyObject).toOpaque())
     
        /*
         4、 根据 3 的内存地址将内存里的内容转为 2 定义的类型
         unsafeBitCast(x, to: type) :将x内存地址的内容强转为 type 类型的内容
     
         blockPtr     : 地址
         BlockType : block 类型
         */
        let newBlock = unsafeBitCast(blockPtr, to: BlockType.self)

最后,将我们得到的newBlock赋值给swift中的Block就搞定啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 下划线和self.的区别 1.通过self. 访问,包含了set和get方法。通过下划线是获取自己的实例变量,不包...
    A_rcher34阅读 859评论 0 3
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,121评论 29 470
  • 点赞再看,养成习惯,白嫖不好,欢迎大家关注我面试小专栏 : iOS中高级进阶之路 有我准备的一线大厂面试资料和简历...
    iOS弗森科阅读 4,292评论 1 35
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,082评论 1 32
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,030评论 0 4