2013-02-24 34 views
12

पर मुख्य दृश्य जोड़ना मैं .NET और जावा पृष्ठभूमि से आने वाले उद्देश्य सी के लिए नया हूं।पृष्ठभूमि थ्रेड पर एक दृश्य बनाते हुए, इसे मुख्य थ्रेड

bool _WebTryThreadLock(bool), 0xa1b8d70: Tried to obtain the web lock from a thread other 
    than the main thread or the web thread. This may be a result of calling to UIKit from a 
    secondary thread. Crashing now... 

तो मैं कैसे जोड़ सकते हैं: एक त्रुटि फेंकता

तो मैं अतुल्यकालिक रूप से कुछ UIwebviews बनाने की जरूरत है, मैं

 dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); 
    dispatch_async(queue, ^{ 
     // create UIwebview, other things too 
      [self.view addSubview:webView]; 
     }); 

का उपयोग कर आप इस कल्पना owuld के रूप में अपने ही कतार पर यह कर रहा हूं मुख्य धागे पर सबव्यू?

उत्तर

16

में जोड़ने के लिए कोशिश कर रहे हैं। मैं performSelectorOnMainThread:withObject:waitUntilDone: का उपयोग नहीं करता, बल्कि मुख्य कतार पर उप-दृश्य जोड़ता हूं।

dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); 
dispatch_async(queue, ^{ 
    // create UIwebview, other things too 

    // Perform on main thread/queue 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.view addSubview:webView]; 
    }); 
}); 

यह एक पृष्ठभूमि कतार पर UIWebView का दृष्टांत को ठीक है। लेकिन इसे एक सबव्यू के रूप में जोड़ने के लिए आपको मुख्य धागे/कतार पर होना चाहिए। UIView प्रलेखन से:

थ्रेडिंग विचार अपने आवेदन की यूजर इंटरफेस के लिए

जोड़तोड़ मुख्य थ्रेड पर होने चाहिए। इस प्रकार, आपको हमेशा अपने आवेदन के मुख्य धागे में चल रहे कोड से UIView क्लास के तरीकों को कॉल करना चाहिए। केवल एक बार यह सख्ती से आवश्यक नहीं हो सकता है जब दृश्य वस्तु स्वयं बनाते हैं लेकिन अन्य सभी जोड़ों को मुख्य धागे पर होना चाहिए।

+0

सावधान रहें, यहां तक ​​कि initWithFrame को थ्रेड सुरक्षित होने की गारंटी नहीं है। http://stackoverflow.com/questions/11122957/is-it-ok-to-create-a-uiview-on-a-background-thread – stefreak

+0

शायद 'थ्रेड-सुरक्षित' की मेरी समझ गलत है। लेकिन मुझे लगता है कि थ्रेड-सुरक्षित का मतलब है कि एक वस्तु को कई धागे से एक साथ छेड़छाड़ की जा सकती है। जैसे आप थ्रेड-सुरक्षित सरणी के बारे में सोच सकते हैं, जो आपको कई धागे से ऑब्जेक्ट्स जोड़ने देगा। हालांकि, इस मामले में हम व्यू ऑब्जेक्ट को कई थ्रेड/कतारों से एक साथ जोड़ या एक्सेस नहीं कर रहे हैं। हम इसे एक थ्रेड/कतार पर बना रहे हैं और फिर अनिवार्य रूप से इसे दूसरे पर सौंप रहे हैं। – Florian

+0

यह पता चला है कि मैंने जो प्रश्न पूछा है वह गलत है - क्षमा करें। ऐप्पल का कहना है कि 'दृश्य वस्तु को स्वयं बनाते समय यह एकमात्र समय सख्ती से जरूरी नहीं है' इसलिए यह सुरक्षित होना चाहिए। – stefreak

2

UIView के उदाहरण सहित अधिकांश UIKit ऑब्जेक्ट्स को मुख्य थ्रेड/कतार से केवल में छेड़छाड़ की जानी चाहिए। आप किसी भी अन्य धागे या कतार पर UIView पर संदेश नहीं भेज सकते हैं। इसका मतलब यह भी है कि आप उन्हें किसी अन्य धागे या कतार पर नहीं बना सकते हैं।

+5

यह पूरी तरह से सही नहीं है। पृष्ठभूमि में एक दृश्य को तुरंत शुरू करना बिल्कुल ठीक है। UIView दस्तावेज़ से: आपके अनुप्रयोग के उपयोगकर्ता इंटरफ़ेस में मैनिपुलेशन मुख्य थ्रेड पर होना चाहिए। इस प्रकार, आपको हमेशा अपने आवेदन के मुख्य धागे में चल रहे कोड से UIView क्लास के तरीकों को कॉल करना चाहिए। केवल एक बार यह सख्ती से आवश्यक नहीं हो सकता है जब दृश्य वस्तु स्वयं बनाते हैं लेकिन अन्य सभी जोड़ों को मुख्य धागे पर होना चाहिए। – Florian

+0

@Florian पृष्ठभूमि में विधि addSubview का उपयोग करने का अधिकार है, यदि दोनों विचार यूआई के साथ बातचीत नहीं करते हैं? –

+0

@ बोहडन सैविच मुझे इसके बारे में निश्चित नहीं है। आपका उपयोग केस क्या है? – Florian

1

के रूप में लूटने कहा यूआई परिवर्तन केवल मुख्य thread.You पर किया जाना चाहिए आप पहले से ही प्रेषण कतारों का उपयोग कर रहे के बाद से एक उच्च माध्यमिक thread.Change से अपने कोड [self.view addSubview:webView];

[self.view performSelectorOnMainThread:@selector(addSubview:) withObject:webView waitUntilDone:YES];