मुख्य थ्रेड चेकर: UI API को बैकग्राउंड थ्रेड पर कॉल किया जाता है: - [UIApplication applicationState]


107

मैं Xcode 9 बीटा, iOS 11 में गूगल मैप्स का उपयोग कर रहा हूं।

मुझे निम्नानुसार लॉग करने के लिए एक त्रुटि मिल रही है:

मुख्य थ्रेड चेकर: UI API को एक बैकग्राउंड थ्रेड पर कॉल किया जाता है: - [UIApplication applicationState] PID: 4442, TID: 837820, थ्रेड नाम: com.google.Maps.LabelingBehavior, कतार नाम: com.apple.root.default-qos.overcommit। , QoS: 21

ऐसा क्यों होगा क्योंकि मैं लगभग निश्चित हूं कि मैं अपने कोड में मुख्य थ्रेड से किसी भी इंटरफ़ेस तत्वों को नहीं बदल रहा हूं।

 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
में mapView(_:didChange)आप भेजने कर रहे हैं printमुख्य कतार में बयान। क्या आप पहले से ही मुख्य कतार में नहीं हैं? यदि नहीं, तो आपको animateकॉल को मुख्य कतार में भेजना होगा । मैं dispatchPrecondition(condition: .onQueue(.main))उन UI अपडेट से पहले कुछ डालने का सुझाव दूंगा , बस यह सुनिश्चित करने के लिए।
राब

आपने कहा "मैं लगभग निश्चित हूं कि मैं अपने कोड में मुख्य थ्रेड से किसी भी इंटरफ़ेस तत्वों को नहीं बदल रहा हूं।" मुझे लगता है कि आपका मतलब "... किसी भी पृष्ठभूमि के धागे से" है।
रोब

2
आपका मुद्दा नहीं। मुझे लगता है कि यह उनके अंत में है। यह "com.google.Maps.LabelingBehavior" में बंद हो जाता है। मेरे पास भी यही कविता है।
टार्वो मेसेप

2
नमस्ते, हाँ, यह किया था, मुद्दा गूगल के साथ झूठ लगता है, उम्मीद है कि वे जल्द ही एक अद्यतन संस्करण जारी करेंगे
मैटब्लैक

1
@MattBlack इस उत्तर पर एक नज़र डालें: stackoverflow.com/a/44392584/5912335
badhanganesh

जवाबों:


54

सबसे पहले, सुनिश्चित करें कि Google मैप्स और ui परिवर्तनों के आपके चालान मुख्य धागे से बुलाए गए हैं।

आप आक्रामक लाइनों को खोजने के लिए थ्रेड सैनिटाइज़र को सक्षम कर सकते हैं।

आप मुख्य सूत्र पर निम्नलिखित पंक्तियों को रख सकते हैं:

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

इसके अलावा, Google मानचित्र के अपने वर्तमान संस्करण को अपडेट करें। Google मैप्स को थ्रेड चेकर के लिए कुछ अपडेट करना था।

प्रश्न के लिए: "ऐसा क्यों होगा?" मुझे लगता है कि Apple ने एक एज केस के लिए एक जोर दिया , जिसके लिए Google को अपने पॉड को अपडेट करना पड़ा।


1
@thibautnoah, क्या आप ऐसा कह रहे हैं क्योंकि मैंने इसे "यह (समस्या) के रूप में वाक्यांश नहीं दिया है क्योंकि आप Google के एपीआई के साथ संयोजन में xcode 9 बीटा का उपयोग कर रहे हैं?" या क्योंकि आप एक समान बग का सामना कर रहे हैं जो मेरे जवाब से हल नहीं होता है?
स्कूटीब्लैड्स

7
Xcode 9 ने कुछ थ्रेडिंग मुद्दों पर प्रकाश डाला, जो xcode 8 को स्पष्ट रूप से पता नहीं लगाता है (क्या यह xcode सेटिंग्स के कारण है या किसी अन्य चीज को निर्धारित किया जाना है)। Xcode 8 पर वापस जाना आपके थ्रेडिंग मुद्दों को अनदेखा करने के बराबर है, वे अभी भी वहां हैं और हल नहीं हैं, इस प्रकार यह कोई समाधान नहीं है, आप सिर्फ रेत में अपना सिर दफन कर रहे हैं और सब कुछ ठीक है। यदि समस्या किसी फ्रेमवर्क से आ रही है तो कृपया एक समस्या प्रस्तुत करें ताकि इसे ठीक किया जा सके।
थिबुत नोह

Xcode 9 उन थ्रेडिंग मुद्दों का पता लगाता है जिनका पता लगाने के लिए Xcode 8 का अनुपात नहीं है, और Google की API संभावना के साथ संयोजन में Xcode 9 इस बग का कारण नहीं बनता है। यह बग कई क्रैश के लिए डीबगर में बैठा है और क्रैश तब नहीं होता है जब आप xcode 8 पर वापस जाते हैं।
स्कॉट्टीब्लाड्स

आप इंगित करते हैं कि थ्रेड चेकर लक्षण दिखा रहा है कारण नहीं। मैं कह रहा हूँ Xcode 9 बीटा दोनों कारण और लक्षण संप्रेषक है। "जब आप xcode 8 पर वापस जाते हैं तो क्रैश नहीं होता है"। डिबगर रीडआउट के साथ XCode चेतावनियों और वास्तविक क्रैश के बीच अंतर है। यह त्रुटि चेतावनी या क्रैश के रूप में दिखाई दे सकती है। दुर्घटना पूरी तरह से दूर हो जाती है जब xcode 8 पर वापस जाते हैं। Xcode 9 बीटा को अच्छे कारण के लिए बीटा कहा जाता है।
स्कॉट्टीब्लाड्स

2
हाँ ... मुझे लगता है कि कई आईओएस डेवलपर्स के लिए यह देखना मुश्किल है कि सिर्फ इसलिए कि कुछ लक्षण दिखा रहा है, इसका मतलब यह नहीं है कि यह कारण के रूप में अच्छी तरह से नहीं है। मुझे लगता है कि यह स्वीकार करना भी मुश्किल है कि एप्पल ने कभी गलती की होगी।
स्कॉट्टीब्लाड्स

156

UI कोड को खोजना मुश्किल है जो कभी-कभी मुख्य थ्रेड में निष्पादित नहीं होता है। आप इसका पता लगाने और इसे ठीक करने के लिए नीचे दिए गए ट्रिक का उपयोग कर सकते हैं।

  1. एडिट स्कीम चुनें -> डायग्नोस्टिक्स, मुख्य थ्रेड चेकर पर टिक करें।

    Xcode 11.4.1

    मेन थ्रेड चेकर ब्रेकपॉइंट बनाने के लिए मेन थ्रेड चेकर के बगल वाले छोटे ऐरो पर क्लिक करें। यहां छवि विवरण दर्ज करें

    पिछला Xcode

    मुद्दों पर रोकें पर टिक करें। यहां छवि विवरण दर्ज करें

  2. इस समस्या को पुन: उत्पन्न करने के लिए अपना iOS एप्लिकेशन चलाएं। (Xcode को पहले मुद्दे पर विराम देना चाहिए।) यहां छवि विवरण दर्ज करें

  3. उस कोड को लपेटें जो UI को संशोधित करता है DispatchQueue.main.async {} यहां छवि विवरण दर्ज करें


4
धन्यवाद, मुझे शायद 30 मिनट बचाओ।
ऑरेंज

10
किसी कारण से, जब मैं Xcode 10.1 में ऐसा करता हूं, तो मुझे केवल एक कॉलस्टैक मिलता है जो असहाय है और मैं एक कोड लाइन से संबंधित नहीं हो सकता: 2018-12-29 19: 46: 56.500629 + 0100 बेडटाइमप्रोटोटाइप [1553: 834478] [रिपोर्ट ] मेन थ्रेड चेकर: UI API को बैकग्राउंड थ्रेड पर बुलाया जाता है: - [UIApplication applicationState] PID: 1553, TID: 834478, Thread name: com.apple.CoreMotion.MotionThread, Queue name: com.apple.root.default-qos। ओवरकमिट, क्यूओएस: 0
विल्मिर डेक्स

1
मुझे एक कॉल स्टैक भी मिला जो असहाय दिखता है। बाएं हाथ की तरफ यह बंद हो गया "com.apple.CoreMotion.MotionThread(23)", फिर मैं अन्य सभी धागे की भी जांच करता हूं। में Thread 1कुछ मेरा ध्यान पकड़ा: यह SVProgressHUD (मैं प्रयोग किया जाता एक प्रगति दृश्य पुस्तकालय) है। तो, मुझे पता है कि यह SVProgressHUD.show()लक्ष्य दृश्य नियंत्रक में कहीं न कहीं एक कॉल है । फिर या तो प्रत्येक उपस्थिति के साथ लपेटें DispatchQueue.main.asyncया बस टिप्पणी करें, फिर से परीक्षण करें और मुझे पता चला कि कौन सा समस्याग्रस्त है।
जॉन पैंग

2
मैंने SVProgressHUD.show टिप्पणी करके चेतावनी से भी छुटकारा पा लिया। इस कॉल को DispatchQueue.main.async में लपेटने से चेतावनी से छुटकारा नहीं मिला। मैं v2.2.5 में फली का उपयोग करता हूं। यह धागा समस्या को बेहतर ढंग से समझने में मदद कर सकता है: github.com/SVProgressHUD/SVProgressHUD/issues/950
Vilmir

1
"मुद्दों पर विराम" चेकबॉक्स मेरे लिए xcode 11.4.1 में नहीं है। संपादित करें: मुझे मेन थ्रेड चेकर के बगल में एक छोटा तीर मिला। क्लिक करना जो आपके लिए एक ब्रेकप्वाइंट जोड़ता है।
क्रिस

47

कोड की पंक्तियों को लपेटें जो UI को संशोधित करते हैं DispatchQueue.main.async {}ताकि यह सुनिश्चित हो सके कि वे मुख्य धागे पर निष्पादित होते हैं। अन्यथा, आप उन्हें पृष्ठभूमि थ्रेड से कॉल कर सकते हैं, जहां UI संशोधनों की अनुमति नहीं है। कोड की ऐसी सभी पंक्तियों को मुख्य धागे से निष्पादित किया जाना चाहिए।


4
हां मैंने पहले ही इसका इस्तेमाल कर लिया है, लेकिन चेतावनी अभी भी मौजूद है
मैटब्लैक

@ पैंग, इसका उपयोग मुख्य यूआई कोड के लिए नहीं, चीजों को प्रिंट करने के लिए किया जाता है।
तोमा

4
@MattBack उन सभी चीजों को लपेटने की कोशिश करता है जो यूआई को संशोधित करते हैंDispatchQueue.main.async {}
टोमा

@ user6603599- एक आकर्षण की तरह काम करता है
श्री

3

इस लिंक का संदर्भ लें https://developer.apple.com/documentation/code_diagnostics/main_thread_checker

मेरे लिए यह तब काम आया जब मैंने ब्लॉक से फोन किया।


1
यदि आप स्विफ्ट 4+ का उपयोग कर रहे हैं, तो यह सबसे अच्छा समाधान सही काम करता है, मेरा समय बचाने के लिए मेरी मदद करने के लिए धन्यवाद। मैंने योजना संपादक के साथ खेला है लेकिन Apple सलाह का पालन करना अब सबसे अच्छा विकल्प है और आगे बढ़ रहा है।
अबूआर्क


-34

योजना चुनें -> निदान, मुख्य थ्रेड चेकर को हटा दें, फिर चेतावनी गायब हो जाएगी। योजना संपादक


18
मुझे नहीं लगता कि यह एक अच्छा विचार है। यहां एक समस्या यह है कि थ्रेड चेकर ने खोज की है। थ्रेड चेकर को अक्षम करने से यह और भविष्य की समस्याओं को अनदेखा करने की अनुमति देगा, और भविष्य के तकनीकी ऋण के कारण मुद्दों को ठीक करने में सक्षम होगा।
ablarg

1
वास्तव में, मेरी बात यह है कि हम यह तब कर सकते हैं जब हम ओपनजीएल एसई प्रतिपादन का उपयोग करते हैं, क्योंकि हम मुख्य थ्रेड में फ्रेम बफर को प्रस्तुत नहीं कर सकते हैं। सही?
एल। पेंग

1
आह, तो अगर युद्ध दिखाई नहीं देता समस्या मौजूद नहीं है?
turingtested

11
"मेरा स्मोक डिटेक्टर बंद क्यों हो रहा है?" "बस बैटरी निकालें, समस्या हल हो गई।"
जॉन मोंटगोमरी

यदि चेतावनी प्रकट नहीं होती है तो समस्या मौजूद नहीं है?
एस गिसेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.