美文网首页
Swift通过extension添加闭包属性,调用闭包时异常问题

Swift通过extension添加闭包属性,调用闭包时异常问题

作者: 字节码 | 来源:发表于2017-02-16 01:19 被阅读146次
以下是发生异常的代码
import UIKit
extension NSObject {

    // MARK: - 定义一个类属性作为闭包容器
    class XYPropertyBlockContainer {

        var viewModelBlock : ViewModelBlock?
        
        var viewMangerInfosBlock : ViewMangerInfosBlock?

        var viewModelInfosBlock : ViewModelInfosBlock?
        
    }
}

问题描述:

Swift项目中再给NSobject类extension中添加类属性作为闭包容器后,在外界创建给这个闭包容器赋值时,发生奔溃,异常内容如下:

*** NSForwarding: warning: object 0x17027acc0 of class '_TtCE10MVVMExapleCSo8NSObject24XYPropertyBlockContainer' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[_TtCE10MVVMExapleCSo8NSObject24XYPropertyBlockContainer copy]

问题分析:
1.通过异常信息可以发现是XYPropertyBlockContainer类未实现copy方法导致的,XYPropertyBlockContainer是我定义的闭包容器类
2.原因这个类我未让它继承自NSObject,当我让其继承自NSObjcet后,再次运行时,再报异常reason: '-[_TtCE10MVVMExapleCSo8NSObject24XYPropertyBlockContainer copyWithZone:]: unrecognized selector sent to instance
3.最后让XYPropertyBlockContainer类继承自NSObjcet且遵守NSCopying协议,重写copy(with zone: NSZone? = nil) -> Any方法解决

解决异常后的代码
import UIKit

extension NSObject {

    typealias ViewModelBlock = () -> Void
    typealias ViewMangerInfosBlock = () -> Void
    typealias ViewModelInfosBlock = () -> Void
    
    // MARK: - 定义一个类属性作为block容器
    class XYPropertyBlockContainer: NSObject, NSCopying {
   
        func copy(with zone: NSZone? = nil) -> Any {
            return self
        }
        
        var viewModelBlock : ViewModelBlock?
        var viewMangerInfosBlock : ViewMangerInfosBlock?
        var viewModelInfosBlock : ViewModelInfosBlock?

    }
    
    // MARK: - 关联属性的key
    private struct RunTimeKey {
        static let blockContainerKey = UnsafeRawPointer(bitPattern: "blockContainerKey".hashValue)
        static let viewMangerDelegateKey = UnsafeRawPointer(bitPattern: "viewMangerDelegate".hashValue)
        static let viewModelDelegateKey = UnsafeRawPointer(bitPattern: "viewModelDelegateKey".hashValue)
        static let xy_viewMangerInfosKey = UnsafeRawPointer(bitPattern: "xy_viewMangerInfosKey".hashValue)
        static let xy_viewModelInfosKey = UnsafeRawPointer(bitPattern: "xy_viewModelInfosKey".hashValue)
        static let xy_mediatorKey = UnsafeRawPointer(bitPattern: "xy_mediatorKey".hashValue)
    }

    /// 闭包容器属性
    var propertyBlockContainer : XYPropertyBlockContainer? {
        set {
            objc_setAssociatedObject(self, RunTimeKey.blockContainerKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        
        get {
            if let blockContainer = objc_getAssociatedObject(self, RunTimeKey.blockContainerKey) as? XYPropertyBlockContainer {
            
                return blockContainer
            }
            return nil
        }
    }
}
注意:外界给闭包容器中的闭包赋值或者调用时,需要先创建闭包容器
@IBAction func btnClick(_ sender: Any) {
        // 传递事件 通过闭包
        if self.propertyBlockContainer == nil {
            self.propertyBlockContainer = XYPropertyBlockContainer()
            self.propertyBlockContainer?.viewModelInfosBlock = {
                print("1+2")
            }
            self.propertyBlockContainer?.viewModelBlock = {
                print("1+3")
            }
            self.propertyBlockContainer?.viewMangerInfosBlock = {
                print("1+4")
            }
            
            self.propertyBlockContainer?.viewMangerInfosBlock!()
            self.propertyBlockContainer?.viewModelBlock!()
            self.propertyBlockContainer?.viewModelInfosBlock!()
        }
        

相关文章

  • Swift通过extension添加闭包属性,调用闭包时异常问题

    以下是发生异常的代码 问题描述: Swift项目中再给NSobject类extension中添加类属性作为闭包容器...

  • 4 iOS类微信日志2018-01-13

    Swift 闭包的使用 步骤: 1. 声明闭包 2. 声明闭包的别名属性 3. 设置回调函数 4. 调用闭包 声明...

  • swift学习

    * 闭包 * 闭包作为属性 ```swift // 声明闭包类型 typealias callba...

  • swift(闭包)

    定义闭包属性 或 或直接构建 闭包函数 调用 逃逸闭包(@escaping) 调用

  • swift 逃逸闭包和非逃逸闭包的区别

    swift 逃逸闭包和非逃逸闭包的区别 逃逸闭包:闭包做为函数的参数传递时,在函数体结束后被调用,我们就说这个闭包...

  • iOS开发随笔

    1.swift3.0后的闭包默认是非逃逸闭包, 所以在逃逸闭包前需要添加@escaping2.instrument...

  • iOS swift 逃逸闭包(@escaping)和非逃逸闭

    iOS swift 逃逸闭包(@escaping)和非逃逸闭包 (@noescaping) 逃逸闭包: 逃逸闭包...

  • Swift-闭包

    Swift 闭包 函数 ()->() Swift 中的闭包和 Objective-C 中的 block 类似,闭包...

  • Swift闭包和函数

    函数在Swift中只是一种特殊的闭包,闭包在Swift语言中是一等公民,支持闭包嵌套和闭包传递。Swift中的闭包...

  • swift4 闭包

    swift 闭包 闭包:swift 中 函数是闭包的一种类似于oc的闭包闭包表达式(匿名函数) -- 能够捕获上下...

网友评论

      本文标题:Swift通过extension添加闭包属性,调用闭包时异常问题

      本文链接:https://www.haomeiwen.com/subject/gdecwttx.html