Swift中的Singleton类给出EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)错误

时间:2019-05-27 12:10:27

标签: ios swift

我正在编写一个快速的Network Manager库,专门满足我自己的API需求。此类声明为final,并且有一个静态let变量来定义此类的单例设计模式。此类中的所有其他函数都是类函数。

不幸的是,每当调用此单例类并使用单例设计模式方法(即static let sharedInstance:NetworkManager = NetworkManager.init())时,它就会给我

  

停止原因= EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)   错误。

我认为线程可能有问题,但是没有。我只是在UIViewController的viewDidLoad中调用了NetworkManager.shared,它给了我同样的错误。

我正在为NetworkManager类提供整个代码

final class NetworkManager {

    static let sharedInstance : NetworkManager = NetworkManager.init()

    private var urlConfig = URLSessionConfiguration.default
    private var urlSession = URLSession(configuration: sharedInstance.urlConfig)

    var basePath : String = "https://api.myjson.com/";

    private init() {

        print("This is getting called at all");
    }
    //MARK:- POST METHODS
    class func performPOST(urlString : String?, bodyParams : [String : AnyObject]? = nil, completionHandler : @escaping(Result<Data?,NetworkError>) -> Void){
        self.performJSON(urlString: urlString, bodyParams: bodyParams, method : .POST, completionHandler: completionHandler)
    }

    class func performPOST( url : URL?, bodyParams : [String : AnyObject]? = nil, headerParams : [String : Any]? = nil,completionHandler : @escaping(Result<Data?,NetworkError>) -> Void){
        self.performJSON(url: url, bodyParams: bodyParams, method : .POST, completionHandler: completionHandler)
    }

    class func performPOST( request : URLRequest?, completionHandler : @escaping(Result<Data?,NetworkError>) -> Void){
       self.performJSON(request: request, completionHandler: completionHandler)
    }

    //MARK:- JSON FUNCTIONS
    class func performJSON(urlString : String?, bodyParams : [String : AnyObject]? = nil, headerParams : [String : Any]? = nil,method : MethodType = .GET , completionHandler : @escaping(Result<Data?,NetworkError>) -> Void){

        guard let urlString = urlString, let compURL = URL.init(string: NetworkManager.sharedInstance.basePath + urlString) else {
            completionHandler(.failure(.badURL))
            return
        }

        var urlReq = URLRequest.init(url: compURL, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 30)

        do {
            try self.prepareTheURLRequest( request : &urlReq,
                                  bodyParams : bodyParams,
                                  headerParams : headerParams,
                                  method :method)
        }catch let error as NetworkError {
             completionHandler(.failure(error))
        }catch let error {
            completionHandler(.failure(NetworkError.unknownError(error)))
        }

        self.performJSON(request: urlReq, completionHandler: completionHandler)
    }

    class func performJSON( url : URL?, bodyParams : [String : AnyObject]? = nil, headerParams : [String : Any]? = nil,method : MethodType = .GET,  completionHandler : @escaping(Result<Data?,NetworkError>) -> Void){
    }

    //MARK:- FIRE_THE_REQUEST
    class func performJSON( request : URLRequest?, completionHandler : @escaping(Result<Data?,NetworkError>) -> Void){
        if let req = request {
            let _ = NetworkManager.sharedInstance.urlSession.dataTask(with: req) { (data, response, error) in
                if let er = error{
                    completionHandler(.failure(NetworkError.unknownError(er)))
                }else if let resp = response{
                    do {
                        try self.validateTheResponse(response: resp)
                        completionHandler(.success(data))
                    } catch let error {
                        completionHandler(.failure(NetworkError.unknownError(error)))
                    }
                }else{
                    completionHandler(.failure(NetworkError.noResponseReceived))
                }
            }
        }
    }

    //MARK:- VALIDATE_RESPONSE
    class func validateTheResponse(response : URLResponse) throws {

        if let httpResponse = response as? HTTPURLResponse {
            let statusCode = httpResponse.statusCode

            switch statusCode {

            case 200 ... 300 :
                break
            default:
                let newError = NSError(domain: "Improper Status Code Received", code: 42, userInfo: ["statusCode":statusCode] )
                throw newError
            }
        }
    }
}

收到的错误如下

  

(lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) frame #0: 0x000000010deab9d3 libdispatch.dylib_dispatch_once_wait + 101 frame #1: 0x000000010bd00579 libswiftCore.dylibswift_once + 25 * frame #2: 0x000000010a7bfcd4 MVVMNetworkManager.sharedInstance.unsafeMutableAddressor at NetworkManager.swift:25:16 frame #3: 0x000000010a7c010a MVVMNetworkManager.(self=0x0000600002756e20).init() at NetworkManager.swift:28:30 frame #4: 0x000000010a7bfca0 MVVMNetworkManager.__allocating_init() at NetworkManager.swift:0 frame #5: 0x000000010a7bfc4c MVVMglobalinit_33_100BB9A6FE18335AA78CDFBEA4A3C62B_func0 at NetworkManager.swift:25:65 frame #6: 0x000000010deaadb5 libdispatch.dylib_dispatch_client_callout + 8 frame #7: 0x000000010deac83d libdispatch.dylib_dispatch_once_callout + 66 frame #8: 0x000000010bd00579 libswiftCore.dylibswift_once + 25 frame #9: 0x000000010a7bfcd4 MVVMNetworkManager.sharedInstance.unsafeMutableAddressor at NetworkManager.swift:25:16 frame #10: 0x000000010a7c06c3 MVVMstatic NetworkManager.performJSON(urlString="bins/9asku", bodyParams=nil, headerParams=nil, method=POST, completionHandler=0x000000010a7cc650 MVVMpartial apply forwarder for closure #1 (Swift.Result, MVVM.NetworkError>) -> () in MVVM.ListRequest.fetchAllLists(completionHandler: (Swift.Result>, MVVM.NetworkError>) -> ()) -> () at , self=0x000000010a7d89e8) at NetworkManager.swift:52:88 frame #11: 0x000000010a7c03fa MVVMstatic NetworkManager.performPOST(urlString="bins/9asku", bodyParams=nil, completionHandler=0x000000010a7cc650 MVVMpartial apply forwarder for closure #1 (Swift.Result, MVVM.NetworkError>) -> () in MVVM.ListRequest.fetchAllLists(completionHandler: (Swift.Result>, MVVM.NetworkError>) -> ()) -> () at , self=0x000000010a7d89e8) at NetworkManager.swift:38:14 frame #12: 0x000000010a7cc547 MVVMListRequest.fetchAllLists(completionHandler=0x000000010a7cf740 MVVMclosure #1 (Swift.Result>, MVVM.NetworkError>) -> () in MVVM.ListPresenter.fetchAndShowList() -> () at ListPresenter.swift:29, self=0x0000600002b1c3a0) at ListRequest.swift:15:24 frame #13: 0x000000010a7cf726 MVVMListPresenter.fetchAndShowList(self=0x0000600002779140) at ListPresenter.swift:29:17 frame #14: 0x000000010a7c5551 MVVMListVC.viewDidAppear(animated=false, self=0x00007ff125e04540) at ListVC.swift:33:25 frame #15: 0x000000010a7c55d3 MVVM@objc ListVC.viewDidAppear(_:) at <compiler-generated>:0 frame #16: 0x000000010edb2536 UIKitCore-[UIViewController _setViewAppearState:isAnimating:] + 942 frame #17: 0x000000010edb521c UIKitCore__64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 42 frame #18: 0x000000010edb35ab UIKitCore-[UIViewController _executeAfterAppearanceBlock] + 75 frame #19: 0x000000010f3b9e05 UIKitCore_runAfterCACommitDeferredBlocks + 634 frame #20: 0x000000010f3a9199 UIKitCore_cleanUpAfterCAFlushAndRunDeferredBlocks + 358 frame #21: 0x000000010f3c7cd9 UIKitCore__34-[UIApplication _firstCommitBlock]_block_invoke_2 + 142 frame #22: 0x000000010ca7eaec CoreFoundationCFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 12 frame #23: 0x000000010ca7e2b0 CoreFoundation__CFRunLoopDoBlocks + 336 frame #24: 0x000000010ca78b34 CoreFoundation__CFRunLoopRun + 1252 frame #25: 0x000000010ca78302 CoreFoundationCFRunLoopRunSpecific + 626 frame #26: 0x0000000114b302fe GraphicsServicesGSEventRunModal + 65 frame #27: 0x000000010f3aeba2 UIKitCoreUIApplicationMain + 140 frame #28: 0x000000010a7caceb MVVMmain at AppDelegate.swift:12:7 frame #29: 0x000000010df1f541 libdyld.dylib`start + 1 (lldb)

2 个答案:

答案 0 :(得分:1)

您的代码中的问题在这一行

private var urlSession = URLSession(configuration: sharedInstance.urlConfig)

就像创建类的实例一样,它的变量也会在内存中分配。但是在这里,您试图在变量完成初始化之前对其进行访问。

要解决崩溃问题,您可以将变量urlSession更改为以下内容:

private var urlSession = URLSession(configuration: URLSessionConfiguration.default)

答案 1 :(得分:0)

在init方法中移动属性的初始化。实例化对象时,您无法访问静态属性>schematics .:simple-schematic "my app" --debug=false CREATE /__name@dasherize__.ts (36 bytes) ,这就是导致崩溃的原因

sharedInstance