DispatchQueue.main.sync 返回 exc_bad_instruction Swift 3

Posted

技术标签:

【中文标题】DispatchQueue.main.sync 返回 exc_bad_instruction Swift 3【英文标题】:DispatchQueue.main.sync returning exc_bad_instruction Swift 3 【发布时间】:2016-10-20 12:35:51 【问题描述】:

我想在我的应用程序中显示一个 ActivityIndi​​catorView,但是当我从主线程调用 sync 方法时,应用程序崩溃并出现错误:exc_bad_instruction (code=exc_i386_invop subcode=0x0) 我正在使用 xcode 8.0 和 swift 3

有人可以帮帮我吗?

 func POST(endpoint:NSString!,body:NSString!,vc:UIViewController? = nil)->NetworkResult
    let result = NetworkResult()
    DispatchQueue.main.sync 
        self.displayActivityIndicator(viewController: vc)
    
    let urlStr = self.url.appending(endpoint as String).appending(self.getHashAutenticacao() as String)
    print(urlStr)
    let request = NSMutableURLRequest(url: URL(string: urlStr)!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20)
    print(request.debugDescription)
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    request.httpBody = body.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: true)

    // send the request
    var data: NSData!
    do 
        data = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning: &self.response) as NSData!
     catch let error1 as NSError 
        self.error = error1
        data = nil
    
    if let httpResponse = self.response as? HTTPURLResponse 
        result.resultCode = httpResponse.statusCode

        if httpResponse.statusCode == 200
            if data != nil
                if data.length > 0
                    let json = (try! JSONSerialization.jsonObject(with: data as Data, options: JSONSerialization.ReadingOptions.mutableContainers))
                    if let jsonArray:NSArray = json as? NSArray
                        result.data = jsonArray
                    else
                        if let jsonDict:NSDictionary = json as? NSDictionary
                            result.data = [jsonDict]
                        
                    
                
            
        
    else 
        result.message = self.error!.debugDescription as NSString?
    

    DispatchQueue.main.sync 
        self.hideActivityIndicator(viewController: vc)
    
    return result

【问题讨论】:

-displayActivityIndicator(_:) 方法在做什么? 不要从服务器同步加载数据,这会导致糟糕的用户体验。习惯异步模式。 我也注意到了这一点,我有一个可以从主线程或辅助线程返回的方法(这可能不是一个好主意,但对我来说很有意义)。我认为这是新事物,因为我从不担心从主线程调度主线程到现在。 【参考方案1】:

您在这里尝试做的是在主线程退出之前从后台线程同步启动它。这是一个逻辑错误。

你应该这样做:

DispatchQueue.global().async(execute: 
    print("teste")
    DispatchQueue.main.sync
        print("main thread")
    
)

【讨论】:

@RodrigoCosta 你想用DispatchQueue.main.sync self.displayActivityIndicator(viewController: vc) 达到什么目的? 方法POST需要返回数据给调用者,方法displayActivityIndi​​cator,在vc.view中显示一个UIActivityIndi​​catorView。我不能使用异步,因为我需要从帖子返回的数据。 方法POST需要返回数据给调用者,方法displayActivityIndi​​cator,在vc.view中显示一个UIActivityIndi​​catorView。我不能使用异步,因为我需要从帖子返回的数据。 @RodrigoCosta 它永远不会工作。阅读此问题的公认答案:***.com/questions/31776114/…。这是正确的做法。 @RodrigoCosta 欢迎您。如果您接受,我将不胜感激。【参考方案2】:

可能是因为您尝试从主线程 DispatchQueue.main.sync。您可以检查您是否已经在主线程中,例如:

if Thread.isMainThread 
  // do stuff
 else 
  DispatchQueue.main.sync 
    // do stuff
  

【讨论】:

谢谢,节省了我一些时间。虽然在主线程上调用DispatchQueue.main.sync 会导致错误,但我觉得有点奇怪。 没什么奇怪的。您将要在主线程上执行的代码块。所以,如果它已经在主线程上,那是明显的错误..)【参考方案3】:

如果你想从主线程读取值,这里有一个方便的函数:

func syncMain<T>(_ closure: () -> T) -> T 
    if Thread.isMainThread 
        return closure()
     else 
        return DispatchQueue.main.sync(execute: closure)
    

用法:

// we are in BG or Main, does not matter
let value = syncMain 
    // we are in Main for sure
    return ...

【讨论】:

以上是关于DispatchQueue.main.sync 返回 exc_bad_instruction Swift 3的主要内容,如果未能解决你的问题,请参考以下文章

当我们从 FireStore 检索数据时,tableview.reloaddata() 在 Dispatchqueue.main.sync 之外仍然有效

GCD 主线程崩溃问题(需要解释)?

全返系统开发

顺丰同城开放平台返点吗

消费全返系统的时代

非返不可小程序开发