当我在模拟器中运行我的应用程序时,我在控制台中获取此日志。 Haven在iOS 8中没有看到这个。我不太清楚是什么造成这种情况。有没有其他人遇到同样的问题,如果是这样,它是如何解决的?或者是否有人可以提供任何帮助?
答案 0 :(得分:67)
除了主线程之外,不要更改UI。虽然它似乎可以在某些操作系统或设备上运行而不是其他操作系统,但它必然会使您的应用程序不稳定,并且无法预测崩溃。
如果您必须回复可以在后台发生的通知,请确保在主线程上发生UIKit
调用 。
你至少有这两个选项:
如果可以在任何线程上通知您的观察者,请使用GCD
(Grand Central Dispatch)。您可以从任何线程监听并执行工作,并在dispatch_async
:
dispatch_async(dispatch_get_main_queue()) {
// Do UI stuff here
}
何时使用GCD
?当您不控制谁发送通知时。它可以是操作系统,Cocoapod,嵌入式库等。使用GCD
每次都会随时醒来。缺点:您发现自己正在重新安排工作。
方便地,您可以使用queue
参数指定您希望观察者通知哪个线程,在您注册时发送通知
addObserverForName:@"notification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
// Do UI stuff here
}
何时在主线程上观察?当您注册和注册时。当您回复通知时,您已经到了需要的位置。
[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];
混合解决方案不保证仅从所述方法调用观察者。它允许更轻的观察者,成本更低的设计。这里只提到解决方案你应该避免。
答案 1 :(得分:20)
Swift 3.0
use(function() {
/*
Business logic
*/
return {
name: valueName,
list: listObject
};
});
答案 2 :(得分:5)
您需要移动到App的MAIN线程中的所有UI部件更新。
我在背景中调用了 createMenuView(),我收到了以下错误
"此应用程序正在从后台线程修改autolayout引擎,这可能导致引擎损坏和奇怪的崩溃"
所以我将上面的方法调用到主线程中使用
$
在SWIFT 3.0和Xcode 8.0中
正确的代码如下:
DispatchQueue.main.async {
}
答案 3 :(得分:3)
您有从后台线程更新UI布局的代码。 更改运行代码的操作队列不需要是显式的。例如,NSURLSession.shared()在发出新请求时不使用主队列。 为了确保您的代码在主线程上运行,我使用了NSOperationQueue的静态方法mainQueue()。
夫特:
NSOperationQueue.mainQueue().addOperationWithBlock(){
//Do UI stuff here
}
的OBJ-C:
[NSOperationQueue mainQueue] addOperationWithBlock:^{
//Do UI stuff here
}];
答案 4 :(得分:3)
符号:
[UIView layoutIfNeeded]`
条件:
!(BOOL)[NSThread isMainThread]
然后将您的UI更新代码放在主线程
中DispatchQueue.main.async {}
答案 5 :(得分:0)
在我的情况下发生同样的问题,我必须以下面的方式更改代码然后它工作正常。
在ViewDidLoad
中,使用main thread
,
[self performSelectorOnMainThread:@selector(setUpTableRows) withObject:nil waitUntilDone:YES];