如何在 Xcode 中回到主线程?
How to get back on Main thread in Xcode?
我正在使用我的 SignUpViewController 创建一个帐户,当用户使用不符合密码规范的密码注册帐户时,程序应该会发出警报。相反,出于某种原因,我不断收到:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
我怎样才能回到主线程,以便程序只发出警报?
这是该视图控制器的代码:
@IBAction func signupPressed(_ sender: Any) {
// Get a reference to the user pool
let userPool = AppDelegate.defaultUserPool()
// Collect all of the attributes that should be included in the signup call
let emailAttribute = AWSCognitoIdentityUserAttributeType(name: "email", value: self.email.text!)
let firstNameAttribute = AWSCognitoIdentityUserAttributeType(name: "given_name", value: self.firstName.text!)
let lastNameAttribute = AWSCognitoIdentityUserAttributeType(name: "family_name", value: self.lastName.text!)
let birthdayAttribute = AWSCognitoIdentityUserAttributeType(name: "birthdate", value: self.birthday.text!)
// Actually make the signup call passing in those attributes
userPool.signUp(UUID().uuidString, password: self.password.text!, userAttributes: [emailAttribute, firstNameAttribute, lastNameAttribute, birthdayAttribute], validationData: nil)
.continueWith { (response) -> Any? in
if response.error != nil {
// Error in the signup process
let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
self.present(alert, animated: true, completion: nil)
} else {
self.user = response.result!.user
// Does user need verification?
if (response.result?.userConfirmed?.intValue != AWSCognitoIdentityUserStatus.confirmed.rawValue) {
// User needs confirmation, so we need to proceed to the verify view controller
DispatchQueue.main.async {
self.performSegue(withIdentifier: "VerifySegue", sender: self)
}
} else {
// User signed up but does not need verification
DispatchQueue.main.async {
self.presentingViewController?.dismiss(animated: true, completion: nil)
}
}
}
return nil
}
}
这也是一个主线程工作
DispatchQueue.main.async {
let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
self.present(alert, animated: true, completion: nil)
}
顺便说一句,如果所有事情都需要在 main
中完成,那么您只能用 1 个 DispatchQueue.main.async
来包围响应
在你的闭包中,如果 error 不是 nil,你能不能像下面这样更新代码并重试:
if response.error != nil {
// Error in the signup process
DispatchQueue.main.async {
let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
self.present(alert, animated: true, completion: nil)
}
}
您已经在编组呈现视图控制器并使用 DispatchQueue.main.async
执行 segue。您还应该这样做以显示 UIAlertController
。您也可以将整个方法主体编组到主线程。
随便写
self.present(alert, animated: true, completion: nil)
在 Dispatch.main.async 中,就像您已经为其他 segues 所做的那样
DispatchQueue.main.async {
self.present(alert, animated: true, completion: nil)
}
除了DispatchQueue.main.async
,我们还可以添加[weak self]
检查来避免循环引用,比如
DispatchQueue.main.async { [weak self] in
self?.present(alert, animated: true, completion: nil)
}
我正在使用我的 SignUpViewController 创建一个帐户,当用户使用不符合密码规范的密码注册帐户时,程序应该会发出警报。相反,出于某种原因,我不断收到:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
我怎样才能回到主线程,以便程序只发出警报?
这是该视图控制器的代码:
@IBAction func signupPressed(_ sender: Any) {
// Get a reference to the user pool
let userPool = AppDelegate.defaultUserPool()
// Collect all of the attributes that should be included in the signup call
let emailAttribute = AWSCognitoIdentityUserAttributeType(name: "email", value: self.email.text!)
let firstNameAttribute = AWSCognitoIdentityUserAttributeType(name: "given_name", value: self.firstName.text!)
let lastNameAttribute = AWSCognitoIdentityUserAttributeType(name: "family_name", value: self.lastName.text!)
let birthdayAttribute = AWSCognitoIdentityUserAttributeType(name: "birthdate", value: self.birthday.text!)
// Actually make the signup call passing in those attributes
userPool.signUp(UUID().uuidString, password: self.password.text!, userAttributes: [emailAttribute, firstNameAttribute, lastNameAttribute, birthdayAttribute], validationData: nil)
.continueWith { (response) -> Any? in
if response.error != nil {
// Error in the signup process
let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
self.present(alert, animated: true, completion: nil)
} else {
self.user = response.result!.user
// Does user need verification?
if (response.result?.userConfirmed?.intValue != AWSCognitoIdentityUserStatus.confirmed.rawValue) {
// User needs confirmation, so we need to proceed to the verify view controller
DispatchQueue.main.async {
self.performSegue(withIdentifier: "VerifySegue", sender: self)
}
} else {
// User signed up but does not need verification
DispatchQueue.main.async {
self.presentingViewController?.dismiss(animated: true, completion: nil)
}
}
}
return nil
}
}
这也是一个主线程工作
DispatchQueue.main.async {
let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
self.present(alert, animated: true, completion: nil)
}
顺便说一句,如果所有事情都需要在 main
中完成,那么您只能用 1 个DispatchQueue.main.async
来包围响应
在你的闭包中,如果 error 不是 nil,你能不能像下面这样更新代码并重试:
if response.error != nil {
// Error in the signup process
DispatchQueue.main.async {
let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
self.present(alert, animated: true, completion: nil)
}
}
您已经在编组呈现视图控制器并使用 DispatchQueue.main.async
执行 segue。您还应该这样做以显示 UIAlertController
。您也可以将整个方法主体编组到主线程。
随便写
self.present(alert, animated: true, completion: nil)
在 Dispatch.main.async 中,就像您已经为其他 segues 所做的那样
DispatchQueue.main.async {
self.present(alert, animated: true, completion: nil)
}
除了DispatchQueue.main.async
,我们还可以添加[weak self]
检查来避免循环引用,比如
DispatchQueue.main.async { [weak self] in
self?.present(alert, animated: true, completion: nil)
}