在从主线程访问后,不得从后台线程对 > 布局引擎进行修改

Posted

技术标签:

【中文标题】在从主线程访问后,不得从后台线程对 > 布局引擎进行修改【英文标题】:Modifications to the > layout engine must not be performed from a background thread after it has been accessed from the main thread 【发布时间】:2020-01-25 00:07:21 【问题描述】:

我刚刚为我的 iPhone 下载了 ios 13 和新的 Xcode。我想为 iOS 13 测试我的应用程序,但是当我尝试运行我的应用程序时,它会在几秒钟后给我一个错误。错误:

由于未捕获的异常而终止应用程序 'NSInternalInconsistencyException',原因:'修改 布局引擎不得在其后的后台线程中执行 已从主线程访问。 *** 第一次抛出调用堆栈:(0x191ea9c30 0x191bc40c8 0x192395434 0x19218eb94 0x19218eaa8 0x19218e718 0x1963e6ea8 0x191bbfaf0 0x198984384 0x19634fe54 0x19898468c 0x198997bf4 0x1988dd3e4 0x1989083a0 0x198909388 0x191bbc3c0 0x191bb4dbc 0x191bb6de8 0x191bb6b30 0x191bbcc78) libc++abi.dylib: 以未捕获的方式终止 NSException 类型的异常

在 iOS 12 及更低版本中,一切似乎都正常,我不会收到此错误。有人知道如何修复此错误以及此错误的含义吗?

下载ID:

func Download_ID() 
    let urlString = "https://www.instagram.com/\(self.username_String)/?__a=1"
    guard let url = URL(string: urlString) else  return 
    URLSession.shared.dataTask(with: url)  data, urlResponse, error in
        guard let data = data, error == nil, urlResponse != nil else 
            print(error)
            return
        
        do
        
            let decoder = JSONDecoder()
            let downloadedData_user = try decoder.decode(Website.self, from: data)
            DispatchQueue.main.async 
                self.profile_img_String = downloadedData_user.graphql.user.profile_pic_url
                let Veri = downloadedData_user.graphql.user.is_verified
                if Veri == true 
                    self.Verified!.isHidden = false
                else
                    self.Verified!.isHidden = true

                
                self.Name!.text = downloadedData_user.graphql.user.full_name
                self.username!.text = self.username_String
                let url = URL(string: "\(self.profile_img_String)")
                self.profileImage!.kf.indicatorType = .activity
                self.profileImage!.kf.setImage(
                    with: url,
                    placeholder: UIImage(named: "image-placeholder.png"),
                    options: [
                        .scaleFactor(UIScreen.main.scale),
                        .transition(.fade(0.4)),
                        .cacheOriginalImage
                ])
            
         catch 
            print(error)
        
    .resume()

堆栈:

Main Thread Checker: UI API called on a background thread: -[UIView setHidden:]
PID: 4437, TID: 1560742, Thread name: (none), Queue name: NSOperationQueue 0x10440d330 (QOS: UNSPECIFIED), QoS: 0
Backtrace:
4   Instagram Profile                   0x00000001029c09bc $s17Instagram_Profile21History_TableViewCellC11Download_IDyyFyycfU_y10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 1612
5   Instagram Profile                   0x00000001029c10d4 $s10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 284
6   CFNetwork                           0x0000000195105ffc CFNetServiceBrowserSearchForServices + 95540
7   CFNetwork                           0x00000001951168dc _CFHTTPMessageSetResponseProxyURL + 7680
8   Foundation                          0x0000000192279c60 A99BF5C7-12EA-3700-8798-6522387A8A89 + 1170528
9   Foundation                          0x000000019217b7e8 A99BF5C7-12EA-3700-8798-6522387A8A89 + 129000
10  Foundation                          0x000000019227bfbc A99BF5C7-12EA-3700-8798-6522387A8A89 + 1179580
11  Foundation                          0x000000019217b464 A99BF5C7-12EA-3700-8798-6522387A8A89 + 128100
12  Foundation                          0x000000019227c9e8 A99BF5C7-12EA-3700-8798-6522387A8A89 + 1182184
13  Foundation                          0x000000019227c4a8 A99BF5C7-12EA-3700-8798-6522387A8A89 + 1180840
14  libdispatch.dylib                   0x00000001042bda48 _dispatch_block_async_invoke2 + 144
15  libdispatch.dylib                   0x00000001042af2a8 _dispatch_client_callout + 20
16  libdispatch.dylib                   0x00000001042b2084 _dispatch_continuation_pop + 572
17  libdispatch.dylib                   0x00000001042b1468 _dispatch_async_redirect_invoke + 628
18  libdispatch.dylib                   0x00000001042c0aac _dispatch_root_queue_drain + 356
19  libdispatch.dylib                   0x00000001042c1418 _dispatch_worker_thread2 + 144
20  libsystem_pthread.dylib             0x0000000191bb6a60 _pthread_wqthread + 216
21  libsystem_pthread.dylib             0x0000000191bbcc78 start_wqthread + 8
2019-09-24 23:21:24.917645+0200 Instagram Profile[4437:1560742] [reports] Main Thread Checker: UI API called on a background thread: -[UIView setHidden:]
PID: 4437, TID: 1560742, Thread name: (none), Queue name: NSOperationQueue 0x10440d330 (QOS: UNSPECIFIED), QoS: 0
Backtrace:
4   Instagram Profile                   0x00000001029c09bc $s17Instagram_Profile21History_TableViewCellC11Download_IDyyFyycfU_y10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 1612
5   Instagram Profile                   0x00000001029c10d4 $s10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 284
6   CFNetwork                           0x0000000195105ffc CFNetServiceBrowserSearchForServices + 95540
7   CFNetwork                           0x00000001951168dc _CFHTTPMessageSetResponseProxyURL + 7680
8   Foundation                          0x0000000192279c60 A99BF5C7-12EA-3700-8798-6522387A8A89 + 1170528
9   Foundation                          0x000000019217b7e8 A99BF5C7-12EA-3700-8798-6522387A8A89 + 129000
10  Foundation                          0x000000019227bfbc A99BF5C7-12EA-3700-8798-6522387A8A89 + 1179580
11  Foundation                          0x000000019217b464 A99BF5C7-12EA-3700-8798-6522387A8A89 + 128100
12  Foundation                          0x000000019227c9e8 A99BF5C7-12EA-3700-8798-6522387A8A89 + 1182184
13  Foundation                          0x000000019227c4a8 A99BF5C7-12EA-3700-8798-6522387A8A89 + 1180840
14  libdispatch.dylib                   0x00000001042bda48 _dispatch_block_async_invoke2 + 144
15  libdispatch.dylib                   0x00000001042af2a8 _dispatch_client_callout + 20
16  libdispatch.dylib                   0x00000001042b2084 _dispatch_continuation_pop + 572
17  libdispatch.dylib                   0x00000001042b1468 _dispatch_async_redirect_invoke + 628
18  libdispatch.dylib                   0x00000001042c0aac _dispatch_root_queue_drain + 356
19  libdispatch.dylib                   0x00000001042c1418 _dispatch_worker_thread2 + 144
20  libsystem_pthread.dylib             0x0000000191bb6a60 _pthread_wqthread + 216
21  libsystem_pthread.dylib             0x0000000191bbcc78 start_wqthread + 8
2019-09-24 23:21:25.431565+0200 Instagram Profile[4437:1560883] WF: _userSettingsForUser mobile: 
    filterBlacklist =     (
    );
    filterWhitelist =     (
    );
    restrictWeb = 1;
    useContentFilter = 0;
    useContentFilterOverrides = 0;
    whitelistEnabled = 0;

2019-09-24 23:21:25.431612+0200 Instagram Profile[4437:1560883] WF: _WebFilterIsActive returning: NO
2019-09-24 23:21:26.084697+0200 Instagram Profile[4437:1560883] WF: _userSettingsForUser mobile: 
    filterBlacklist =     (
    );
    filterWhitelist =     (
    );
    restrictWeb = 1;
    useContentFilter = 0;
    useContentFilterOverrides = 0;
    whitelistEnabled = 0;

2019-09-24 23:21:26.084745+0200 Instagram Profile[4437:1560883] WF: _WebFilterIsActive returning: NO
2019-09-24 23:21:26.150637+0200 Instagram Profile[4437:1560979] NSURLConnection ordering violation: didFinishLoading to be scheduled before didReceiveResponse
2019-09-24 23:21:30.905067+0200 Instagram Profile[4437:1560742] This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
 Stack:(
    0   Foundation                          0x00000001923953a4 A99BF5C7-12EA-3700-8798-6522387A8A89 + 2331556
    1   Foundation                          0x000000019218eb94 A99BF5C7-12EA-3700-8798-6522387A8A89 + 207764
    2   Foundation                          0x000000019218eaa8 A99BF5C7-12EA-3700-8798-6522387A8A89 + 207528
    3   Foundation                          0x000000019218e718 A99BF5C7-12EA-3700-8798-6522387A8A89 + 206616
    4   UIKitCore                           0x00000001963e6ea8 EBED47E6-6BB2-3119-82CE-CC13EDCA02D6 + 15568552
    5   libobjc.A.dylib                     0x0000000191bbfaf0 10328337-A06E-370F-8958-6EDDA1F434DC + 6896
    6   QuartzCore                          0x0000000198984384 18D85F6F-635D-3A6F-BF7D-898A644FDCF5 + 1393540
    7   UIKitCore                           0x000000019634fe54 EBED47E6-6BB2-3119-82CE-CC13EDCA02D6 + 14949972
    8   QuartzCore                          0x000000019898468c 18D85F6F-635D-3A6F-BF7D-898A644FDCF5 + 1394316
    9   QuartzCore                          0x0000000198997bf4 18D85F6F-635D-3A6F-BF7D-898A644FDCF5 + 1473524
    10  QuartzCore                          0x00000001988dd3e4 18D85F6F-635D-3A6F-BF7D-898A644FDCF5 + 709604
    11  QuartzCore                          0x00000001989083a0 18D85F6F-635D-3A6F-BF7D-898A644FDCF5 + 885664
    12  QuartzCore                          0x0000000198909388 18D85F6F-635D-3A6F-BF7D-898A644FDCF5 + 889736
    13  libsystem_pthread.dylib             0x0000000191bbc3c0 FEB52688-4D65-3D38-AD50-01B128A74208 + 37824
    14  libsystem_pthread.dylib             0x0000000191bb4dbc FEB52688-4D65-3D38-AD50-01B128A74208 + 7612
    15  libsystem_pthread.dylib             0x0000000191bb6de8 FEB52688-4D65-3D38-AD50-01B128A74208 + 15848
    16  libsystem_pthread.dylib             0x0000000191bb6b30 _pthread_wqthread + 424
    17  libsystem_pthread.dylib             0x0000000191bbcc78 start_wqthread + 8
)
2019-09-24 23:21:30.927369+0200 Instagram Profile[4437:1560742] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.'
*** First throw call stack:
(0x191ea9c30 0x191bc40c8 0x192395434 0x19218eb94 0x19218eaa8 0x19218e718 0x1963e6ea8 0x191bbfaf0 0x198984384 0x19634fe54 0x19898468c 0x198997bf4 0x1988dd3e4 0x1989083a0 0x198909388 0x191bbc3c0 0x191bb4dbc 0x191bb6de8 0x191bb6b30 0x191bbcc78)
libc++abi.dylib: terminating with uncaught exception of type NSException

【问题讨论】:

查看 Xcode 中的堆栈跟踪,看看你在哪里导致后台线程的布局更新。 我似乎无法弄清楚,你能帮我在哪里可以找到堆栈跟踪中后台线程的更新吗? 从堆栈跟踪的外观来看,您正在从网络获取一些 Instagram 个人资料数据;确保此代码的完成处理程序在更新 Ui 之前分派回主队列 @Paulw11 感谢您的回复!我不确定我需要做什么来解决它。我添加了从 instagram 获取数据的功能。 面临同样的问题.. iOS 12 运行良好...... iOS 13 我遇到了问题 【参考方案1】:

您的网络获取代码几乎是正确的 - 您正在重新加载主队列中的表,但没有停止活动指示器。

你只需要在闭包内移动那条线:

let downloadedData_user = try decoder.decode(Top_us.self, from: data)
    self.Top_Search = downloadedData_user.users
    DispatchQueue.main.async 
        self.tableView.reloadData()
        self.Indicator.stopAnimating()
    

请注意,按照惯例,属性应以小写字母开头,而类应以大写字母开头。两者都应该使用驼峰式,所以Top_Search 应该是topSearchTop_us 应该是TopUsersIndicator 应该是indicator

【讨论】:

感谢您的回复,但它似乎没有奏效。我仍然遇到同样的错误! 仔细查看堆栈跟踪,您正在表格视图单元格的Download_ID 中执行网络操作 - 这也是从后台队列更新 UI。 你找到解决办法了吗?【参考方案2】:

对于任何在确定原因时遇到问题的人,请尝试以下操作。

单击您的方案(在停止按钮旁边),然后编辑方案

Run -> Diagnostics 下你必须激活 Main Thread Checker

正如添加的断点所示,当您尝试在非主线程上更改 UI 时,您的执行现在将停止。

编辑

当没有添加断点时。可以在下面手动添加:

断点导航器 -> + -> 运行时问题断点 -> 编辑 -> 类型 -> 主线程检查器

【讨论】:

到目前为止最有用的答案在这里。谢谢你,好心的先生! 如果我可以再投票 5 次,我会......因为这个而发现问题 我按照这些说明进行操作,但断点导航器没有显示添加的断点。它根本不显示任何断点。 哇,绝对的救命稻草 这个答案在 2022 年仍在挽救生命【参考方案3】:

你应该用DispatchQueue.main.async包装处理错误

func Download_ID() 
    let urlString = "https://www.instagram.com/\(self.username_String)/?__a=1"
    guard let url = URL(string: urlString) else  return 
    URLSession.shared.dataTask(with: url)  data, urlResponse, error in
        guard let data = data, error == nil, urlResponse != nil else 
            // Add DispatchQueue
            DispatchQueue.main.async 
              print(error)
            
            return
        
        do
        
            let decoder = JSONDecoder()
            let downloadedData_user = try decoder.decode(Website.self, from: data)
            // your logic
            DispatchQueue.main.async 
               // update or reload table in here
            
         catch 
            // Add dispach_queue
            DispatchQueue.main.async 
              print(error)
            
        
    .resume()

【讨论】:

【参考方案4】:

如果有人像我一样在使用 UIAlertController 时遇到此问题,请尝试将整个警报包装到 DispatchQueue.main.async 中,如下所示:

DispatchQueue.main.async 
//alert:
    let alert = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)
    let ok = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
    alert.addAction(ok)
    self.present(alert, animated: true, completion: nil)

【讨论】:

我的问题只出在 ios14 上,但这个解决了。谢谢!

以上是关于在从主线程访问后,不得从后台线程对 > 布局引擎进行修改的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 3 在 Magical Record 中保存上下文时出错

从主循环访问线程变量 - c++ - windows

请帮忙解释下Dispatcher.BeginInoke((Action)(()=>....;...;...;),null);啥意思?

即使从主线程调用更新,UI 也不会更新

如何从主线程超时java线程?

从服务访问android位置?