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 【问题描述】:我想在我的应用程序中显示一个 ActivityIndicatorView,但是当我从主线程调用 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需要返回数据给调用者,方法displayActivityIndicator,在vc.view中显示一个UIActivityIndicatorView。我不能使用异步,因为我需要从帖子返回的数据。
方法POST需要返回数据给调用者,方法displayActivityIndicator,在vc.view中显示一个UIActivityIndicatorView。我不能使用异步,因为我需要从帖子返回的数据。
@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 之外仍然有效