Swift는 extension을 통해 클립 속성을 추가하고 클립을 호출할 때 비정상적인 문제 해결: does not implement method Signature ForSelector: - trouble ahead Unrecognized selector - [TtCE10 MVVMExapleCSo8 NSObject24XYProperty BlockContainer copy]

3885 단어
다음은 이상이 발생한 코드입니다
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.이상 정보를 통해 알 수 있듯이 XYProperty BlockContainer 클래스가copy 방법을 실현하지 않아서 발생한 것이다. XYProperty BlockContainer는 내가 정의한 패키지 용기 클래스이다.왜냐하면 이 클래스는 NSObject에서 계승되지 않았습니다. NSObjcet에서 계승된 후에 다시 실행할 때 이상 보고reason: '-[_TtCE10MVVMExapleCSo8NSObject24XYPropertyBlockContainer copyWithZone:]: unrecognized selector sent to instance3.마지막으로 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!()
        }
        

좋은 웹페이지 즐겨찾기