美文网首页
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添加闭包属性,调用闭包时异常问题

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