DispatchQueue.main.sync returning exc_bad_instruction Swift 3
19,448
Solution 1
What you are trying to do here is to launch the main thread synchronously from a background thread before it exits. This is a logical error.
You should do it like this:
DispatchQueue.global().async(execute: {
print("teste")
DispatchQueue.main.sync{
print("main thread")
}
})
Solution 2
Maybe it's because you are trying to DispatchQueue.main.sync from the Main thread. You can check if you are already in the main thread like:
if Thread.isMainThread {
// do stuff
} else {
DispatchQueue.main.sync {
// do stuff
}
}
Solution 3
If you want to read the value from the main thread, here is a handy function:
func syncMain<T>(_ closure: () -> T) -> T {
if Thread.isMainThread {
return closure()
} else {
return DispatchQueue.main.sync(execute: closure)
}
}
Usage:
// we are in BG or Main, does not matter
let value = syncMain {
// we are in Main for sure
return ...
}
Related videos on Youtube
Author by
Rodrigo Costa
Updated on July 01, 2022Comments
-
Rodrigo Costa almost 2 years
I want to display an ActivityIndicatorView in my app, but when I call the
sync
method from the main thread, the app crashes with the error:exc_bad_instruction (code=exc_i386_invop subcode=0x0)
I'm using xcode 8.0 and swift 3Can someone please help me?
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 }
-
holex over 7 yearswhat is
-displayActivityIndicator(_:)
method doing? -
vadian over 7 yearsDo not load data form a server synchronously, it causes bad user experience. Get used to the asynchronous pattern.
-
Cristi Băluță about 7 yearsI just noticed this too, i have a method that can return from main or secondary thread (which probably is not such a good idea but it makes sense for my case). I think is something new because i never worried about dispatching main thread from main thread till now.
-
-
Max Pevsner over 7 years@RodrigoCosta what are you trying to achieve with
DispatchQueue.main.sync { self.displayActivityIndicator(viewController: vc) }
? -
Rodrigo Costa over 7 yearsThe method POST needs to return data to the caller, the method displayActivityIndicator, displays an UIActivityIndicatorView into vc.view. I can't use async because i need data returned from the post.
-
Rodrigo Costa over 7 yearsThe method POST needs to return data to the caller, the method displayActivityIndicator, displays an UIActivityIndicatorView into vc.view. I can't use async because i need data returned from the post.
-
Max Pevsner over 7 years@RodrigoCosta it will never work. Read the accepted answer to this question: stackoverflow.com/questions/31776114/…. It is the proper way to do it.
-
Max Pevsner over 7 years@RodrigoCosta welcome. I would appreciate, if you accept it.
-
Ting Yi Shih almost 6 yearsWhy does
DispatchQueue.main.sync
mean I launch it from a background thread? -
Wizard over 5 yearsThanks, saved me some time. I find it kind of strange though that calling
DispatchQueue.main.sync
on the main thread leads to an error. -
GeoSD over 4 yearsThere is nothing strange. You put block of code to be executed on main thread. So, if it already on main thread, that's obvious error..)