Je reçois ce journal dans la console lorsque j'exécute mon application dans son simulateur. Je n'ai pas vu cela dans iOS 8. Je ne sais pas trop ce qui cause cela. Quelqu'un at-il rencontré le même problème et si oui, comment a-t-il été résolu? ou y a-t-il de l'aide que quelqu'un puisse fournir à cet égard?
Ne changez pas l'interface utilisateur à partir de rien d'autre que du fil principal. Bien que cela puisse sembler fonctionner sur certains systèmes d'exploitation ou périphériques et pas sur d'autres, cela rendra votre application instable et provoquera un crash imprévisible.
Si vous devez répondre à une notification qui peut se produire en arrière-plan, assurez-vous que UIKit
invocation a lieu sur le thread principal .
Vous avez au moins ces 2 options:
Utilisez GCD
(Grand Central Dispatch) si votre observateur peut être averti sur n’importe quel fil. Vous pouvez écouter et travailler à partir de n’importe quel thread et encapsuler les modifications de l’UI dans un dispatch_async
:
dispatch_async(dispatch_get_main_queue()) {
// Do UI stuff here
}
Quand utiliser GCD
? Lorsque vous ne contrôlez pas qui envoie la notification. Cela peut être le système d'exploitation, un Cocoapod, des bibliothèques intégrées, etc. L'utilisation de GCD
se réveillera à tout moment, à tout moment. Inconvénient: vous vous retrouvez à réorganiser le travail.
De manière pratique, vous pouvez spécifier sur quel thread vous souhaitez que l'observateur soit averti, au moment de votre enregistrement pour les notifications, à l'aide du paramètre queue
:
addObserverForName:@"notification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
// Do UI stuff here
}
Quand observer sur le fil principal? Lorsque vous vous inscrivez et que vous vous inscrivez. Dès que vous répondez à la notification, vous êtes déjà là où vous devez être.
[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];
Solution hybride qui ne garantit pas que l’observateur n’est appelé que de cette méthode. Cela permet d'avoir un observateur plus léger, au prix d'une conception moins robuste. Seulement mentionné ici comme solution vous devriez probablement éviter.
Swift 3.0
DispatchQueue.main.async {
}
Toute la mise à jour de la partie de l'interface utilisateur doit être déplacée dans le fil MAIN de l'App.
J'appelais un createMenuView () en arrière-plan et j'ai eu l'erreur ci-dessous
"Cette application modifie le moteur d'autolayout à partir d'un thread en arrière-plan, ce qui peut entraîner une corruption du moteur et des accidents étranges"
J'ai donc appelé la méthode ci-dessus dans le fil principal à l'aide de
DispatchQueue.main.async {
}
dans Swift 3.0 et Xcode 8.0
Code correct écrit ci-dessous:
RequestAPI.post(postString: postString, url: "https://www.someurl.com") { (succeeded: Bool, msg: String, responceData:AnyObject) -> () in
if(succeeded) {
print(items: "User logged in. Registration is done.")
// Move to the UI thread
DispatchQueue.main.async (execute: { () -> Void in
//Set User's logged in
Util.set_IsUserLoggedIn(state: true)
Util.set_UserData(userData: responceData)
self.appDelegate.createMenuView()
})
}
else {
// Move to the UI thread
DispatchQueue.main.async (execute: { () -> Void in
let alertcontroller = UIAlertController(title: JJS_MESSAGE, message: msg, preferredStyle: UIAlertControllerStyle.alert)
alertcontroller.title = "No Internet"
alertcontroller.message = FAILURE_MESSAGE
self.present(alertcontroller, animated: true, completion: nil)
})
}
}
Vous disposez d'un code qui met à jour la présentation de l'interface utilisateur à partir d'un thread en arrière-plan . La modification de la file d'attente des opérations sur laquelle vous exécutez votre code n'a pas besoin d'être explicite. Par exemple, NSURLSession.shared () n'utilise pas la file d'attente principale lors de nouvelles requêtes. Pour m'assurer que votre code fonctionne sur le thread principal, j'utilise la méthode statique de NSOperationQueue, mainQueue ().
Rapide:
NSOperationQueue.mainQueue().addOperationWithBlock(){
//Do UI stuff here
}
Obj-C:
[NSOperationQueue mainQueue] addOperationWithBlock:^{
//Do UI stuff here
}];
Le même problème s’est produit dans mon cas, je dois changer le code de la manière suivante, puis cela fonctionne très bien . Dans ViewDidLoad
, appelez cette méthode en utilisant main thread
,
[self performSelectorOnMainThread:@selector(setUpTableRows) withObject:nil waitUntilDone:YES];