Trình kiểm tra luồng chính: API giao diện người dùng được gọi trên luồng nền: - [UIApplication applicationState]


107

Tôi đang sử dụng bản đồ google trong Xcode 9 beta, iOS 11.

Tôi gặp lỗi được xuất ra nhật ký như sau:

Trình kiểm tra chuỗi chính: API giao diện người dùng được gọi trên chuỗi nền: - [UIApplication applicationState] PID: 4442, TID: 837820, Thread name: com.google.Maps.LabelingBehavior, Queue name: com.apple.root.default-qos.overcommit , QoS: 21

Tại sao điều này lại xảy ra vì tôi gần như chắc chắn rằng tôi không thay đổi bất kỳ phần tử giao diện nào từ chuỗi chính trong mã của tôi.

 override func viewDidLoad() {

    let locationManager = CLLocationManager()


    locationManager.requestAlwaysAuthorization()


    locationManager.requestWhenInUseAuthorization()

        if CLLocationManager.locationServicesEnabled() {

            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
        }

      viewMap.delegate = self

     let camera = GMSCameraPosition.camera(withLatitude: 53.7931183329367, longitude: -1.53649874031544, zoom: 17.0)


        viewMap.animate(to: camera)


    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
    }

    func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {


    }

    func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {

        if(moving > 1){
            moving = 1
        UIView.animate(withDuration: 0.5, delay: 0, animations: {

            self.topBarConstraint.constant = self.topBarConstraint.constant + (self.topBar.bounds.height / 2)

            self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant + (self.topBar.bounds.height / 2)

            self.view.layoutIfNeeded()
        }, completion: nil)
    }
         moving = 1
    }


    // Camera change Position this methods will call every time
    func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
        moving = moving + 1
        if(moving == 2){


            UIView.animate(withDuration: 0.5, delay: 0, animations: {


                self.topBarConstraint.constant = self.topBarConstraint.constant - (self.topBar.bounds.height / 2)

                self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant - (self.topBar.bounds.height / 2)


                self.view.layoutIfNeeded()
            }, completion: nil)
        }
        DispatchQueue.main.async {

            print("Moving: \(moving) Latitude: \(self.viewMap.camera.target.latitude)")
            print("Moving: \(moving)  Longitude: \(self.viewMap.camera.target.longitude)")
        }
    }

1
Trong mapView(_:didChange)bạn đang gửi các printcâu lệnh đến hàng đợi chính. Bạn chưa ở trong hàng đợi chính? Nếu không, bạn cũng phải gửi animatecuộc gọi đến hàng đợi chính. Tôi khuyên bạn nên chèn một số dispatchPrecondition(condition: .onQueue(.main))trước khi cập nhật giao diện người dùng đó, chỉ để đảm bảo.
Rob

Bạn đã nói "Tôi gần như chắc chắn rằng tôi không thay đổi bất kỳ thành phần giao diện nào từ luồng chính trong mã của mình." Tôi cho rằng ý của bạn là "... từ bất kỳ chuỗi nền nào."
Rob

2
Không phải vấn đề của bạn. Tôi điều đó là ở cuối của họ. Nó dừng lại ở "com.google.Maps.LabelingBehavior". Tôi có cùng một vấn đề.
Tarvo Mäesepp

2
Hi, vâng nó đã làm, vấn đề này dường như lời nói dối với google, hy vọng họ sẽ phát hành một phiên bản cập nhật sớm
MattBlack

1
@MattBlack Hãy xem câu trả lời này: stackoverflow.com/a/44392584/5912335
badhanganesh 21/09/17

Câu trả lời:


53

Trước tiên, hãy đảm bảo rằng các lệnh gọi google maps và các thay đổi ui của bạn được gọi từ chuỗi chính.

Bạn có thể bật Chủ đề Sanitizer để tìm dòng xúc phạm.

Bạn có thể đặt các dòng vi phạm trên chuỗi chính với những điều sau:

DispatchQueue.main.async {
    //Do UI Code here. 
    //Call Google maps methods.
}

Ngoài ra, hãy cập nhật phiên bản google maps hiện tại của bạn. Google maps đã phải thực hiện một vài bản cập nhật cho trình kiểm tra luồng.

Đối với câu hỏi: "Tại sao điều này lại xảy ra?" Tôi nghĩ rằng Apple đã thêm một xác nhận cho một trường hợp cạnh mà Google sau đó phải cập nhật pod của họ.


1
@thibautnoah, có phải bạn đang nói vậy bởi vì tôi đã không đặt cụm từ là "nó (sự cố) đang xảy ra vì bạn đang sử dụng xcode 9 beta kết hợp với API của Google không?" Hay vì bạn đang phải đối mặt với một lỗi tương tự mà câu trả lời của tôi không giải quyết được?
ScottyBlades:

7
Xcode 9 đã nêu bật một số vấn đề về luồng mà xcode 8 dường như không phát hiện được (cho dù đó là do cài đặt xcode hay một thứ khác cần được xác định). Chuyển về xcode 8 tương đương với việc bỏ qua các vấn đề về luồng của bạn, chúng vẫn ở đó và chưa được giải quyết, do đó nó không phải là giải pháp, bạn chỉ đang vùi đầu vào cát và giả vờ mọi thứ đều ổn. Nếu sự cố đến từ một khuôn khổ, vui lòng gửi sự cố để nó có thể được khắc phục.
thibaut noah

Xcode 9 phát hiện các vấn đề phân luồng mà xcode 8 không proport để phát hiện, VÀ Xcode 9 kết hợp với API của Google có thể gây ra lỗi này. Lỗi này tọa lạc trong một trình gỡ lỗi cho nhiều tai nạn và những tai nạn không còn xảy ra khi bạn chuyển về xcode 8.
ScottyBlades

Ý của bạn là bộ kiểm tra luồng đang hiển thị triệu chứng không phải nguyên nhân. Tôi đang nói Xcode 9 beta vừa là nguyên nhân VÀ vừa là tác nhân truyền triệu chứng. "sự cố không còn xảy ra khi bạn chuyển về xcode 8". Có sự khác biệt giữa cảnh báo XCode và sự cố thực tế khi đọc trình gỡ lỗi. Lỗi này có thể hiển thị dưới dạng cảnh báo HOẶC sự cố. Sự cố sẽ biến mất hoàn toàn khi chuyển trở lại xcode 8. Xcode 9 beta được gọi là beta vì một lý do chính đáng.
ScottyBlades,

2
Vâng ... Tôi nghĩ rằng thật khó để nhiều nhà phát triển ios thấy rằng chỉ vì một cái gì đó đang hiển thị triệu chứng, không có nghĩa là nó cũng không chắc chắn là nguyên nhân. Tôi nghĩ cũng khó chấp nhận rằng Apple có thể đã từng mắc sai lầm.
ScottyBlades,

156

Thật khó để tìm thấy mã giao diện người dùng đôi khi không được thực thi trong luồng chính. Bạn có thể sử dụng thủ thuật dưới đây để xác định vị trí và sửa lỗi.

  1. Chọn Edit Scheme -> Diagnostics, đánh dấu vào Main Thread Checker.

    Xcode 11.4.1

    Nhấp vào mũi tên nhỏ bên cạnh Bộ kiểm tra luồng chính để tạo điểm ngắt của Bộ kiểm tra luồng chính. nhập mô tả hình ảnh ở đây

    Xcode trước

    Đánh dấu vào Tạm dừng trên các vấn đề. nhập mô tả hình ảnh ở đây

  2. Chạy ứng dụng iOS của bạn để tái tạo sự cố này. (Xcode sẽ tạm dừng ở vấn đề đầu tiên.) nhập mô tả hình ảnh ở đây

  3. Gói mã sửa đổi giao diện người dùng trong DispatchQueue.main.async {} nhập mô tả hình ảnh ở đây


4
Cảm ơn, có thể tiết kiệm cho tôi 30 phút.
Orange

10
Vì một số lý do, khi tôi làm điều đó trong Xcode 10.1, tôi chỉ nhận được một callstack bất lực và tôi không thể liên quan đến dòng mã: 2018-12-29 19: 46: 56.500629 + 0100 BedtimePrototype [1553: 834478] [báo cáo ] Trình kiểm tra luồng chính: API giao diện người dùng được gọi trên luồng nền: - [UIApplication applicationState] PID: 1553, TID: 834478, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos. overcommit, QoS: 0
Vilmir 29/12/18

1
Tôi cũng có một ngăn xếp cuộc gọi trông bất lực. Ở phía bên trái, nó dừng lại ở "com.apple.CoreMotion.MotionThread(23)", sau đó tôi kiểm tra tất cả các chủ đề khác. Trong Thread 1một thứ khiến tôi chú ý: đó là SVProgressHUD (một thư viện xem tiến trình mà tôi đã sử dụng). Vì vậy, tôi biết đó là một cuộc gọi đến SVProgressHUD.show()một nơi nào đó trong bộ điều khiển chế độ xem mục tiêu. Sau đó, hoặc kết thúc mỗi lần xuất hiện bằng DispatchQueue.main.asynchoặc chỉ cần bình luận, kiểm tra lại và tôi phát hiện ra cái nào có vấn đề.
John Pang

2
Tôi cũng đã thoát khỏi cảnh báo bằng cách bình luận ra SVProgressHUD.show. Gói cuộc gọi này thành DispatchQueue.main.async không loại bỏ được cảnh báo. Tôi sử dụng nhóm trong v2.2.5 Chủ đề này có thể giúp hiểu sự cố tốt hơn: github.com/SVProgressHUD/SVProgressHUD/issues/950
Vilmir

1
Tôi không có hộp kiểm "Tạm dừng về sự cố" trong xcode 11.4.1. Chỉnh sửa: Tôi tìm thấy một mũi tên nhỏ bên cạnh Trình kiểm tra luồng chính. Nhấp vào đó sẽ thêm điểm ngắt cho bạn.
ChrisO

47

Gói các dòng mã sửa đổi giao diện người dùng DispatchQueue.main.async {}để đảm bảo chúng thực thi trên chuỗi chính. Nếu không, bạn có thể đang gọi chúng từ một chuỗi nền, nơi không được phép sửa đổi giao diện người dùng. Tất cả các dòng mã như vậy phải được thực thi từ luồng chính.


4
vâng tôi đã sử dụng đó nhưng cảnh báo vẫn còn hiện diện
MattBlack

@Pang, nó được sử dụng để in mọi thứ, không phải cho mã giao diện người dùng chính.
Dimitrie-Toma Furdui

4
@MattBlack cố gắng quấn tất cả những điều mà sửa đổi giao diện người dùng trênDispatchQueue.main.async {}
Dimitrie-Toma Furdui

@ user6603599-Hoạt động như một sự quyến rũ
Sree

3

Tham khảo liên kết này https://developer.apple.com/documentation/code_diagnostics/main_thread_checker

Đối với tôi, điều này đã hoạt động khi tôi gọi từ khối.


1
Nếu bạn đang sử dụng Swift 4+, đây là giải pháp tốt nhất hoạt động hoàn hảo, cảm ơn bạn đã giúp tôi tiết kiệm thời gian. Tôi đã chơi với Scheme Editor nhưng làm theo lời khuyên của Apple là lựa chọn tốt nhất hiện tại và tiến lên phía trước.
AbuTaareq


-34

Chọn lược đồ -> Chẩn đoán, loại bỏ trình kiểm tra luồng chính, sau đó cảnh báo sẽ biến mất. biên tập chương trình


18
Tôi không nghĩ đây là một ý kiến ​​hay. Có một vấn đề ở đây mà trình kiểm tra luồng đã phát hiện ra. Việc tắt trình kiểm tra luồng sẽ cho phép không phát hiện ra vấn đề này và các vấn đề trong tương lai, đồng thời gây ra nợ kỹ thuật trong tương lai để khắc phục sự cố.
ablarg

1
Trên thực tế, quan điểm của tôi là chúng ta có thể làm điều này khi chúng ta sử dụng kết xuất OpenGL, vì chúng ta không thể kết xuất bộ đệm khung trong luồng chính. đúng?
L.Peng

1
Ah, vậy nếu waring không xuất hiện thì vấn đề không tồn tại?
turingtested vào

11
"Tại sao máy dò khói của tôi tiếp tục hoạt động?" "Chỉ cần tháo pin, vấn đề đã được giải quyết."
John Montgomery

Nếu cảnh báo không xuất hiện, sự cố không tồn tại?
S. Gissel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.