2012-06-20 15 views
16

मुझे पता है कि UIView थ्रेड सुरक्षित नहीं है इसलिए मैं पृष्ठभूमि थ्रेड पर एक दृश्य जोड़ नहीं सकता, इसके आसपास काम करने के लिए यह पृष्ठभूमि थ्रेड पर UIView बनाना ठीक है, फिर इसे मुख्य थ्रेड पर जोड़ें?क्या पृष्ठभूमि धागे पर UIView बनाना ठीक है?

नोट: कारण मैं मुख्य धागे पर ऐसा नहीं कर रहा हूं क्योंकि मेरा वास्तविक कोड बहुत जटिल है और सभी विचारों को बनाने और मूल्यों को भरने में कुछ समय लगता है। मैं नहीं चाहता कि यूआई अप्रत्याशित हो जाए, जब मैं ऐसा करता हूं तो मैं इस के आसपास काम करने की कोशिश कर रहा हूं।

उदाहरण के लिए

..

-(void)addLabel//called on background thread 
{ 
    UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0,0,40,100)]; 
    [label setText:@"example"] 
    [self.view performSelector:@selector(addSubview:) onThread:[NSThread mainThread] withObject:example waitUntilDone:YES]; 
} 

अग्रिम धन्यवाद।

+0

मेरा मानना ​​है कि आपके पास यह सही है। इसे पृष्ठभूमि पर बनाएं लेकिन मुख्य पर यूआई अपडेट करें। –

उत्तर

15
UIView से

:

थ्रेडिंग विचार

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

initWithFrame: पर कॉल स्पष्ट रूप से थ्रेड सुरक्षित नहीं है। setText: पर कॉल संभवतः थ्रेड-सुरक्षित नहीं है, जो "मैनिपुलेशन" खंड के अंतर्गत आ रहा है। इन्हें निश्चित रूप से थ्रेड-सुरक्षित होने का वादा नहीं किया जाता है।

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

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

+5

मुझे खेद है लेकिन क्या आप अपना उत्तर स्पष्ट कर सकते हैं ? सेब से उद्धरण विशेष रूप से पृष्ठभूमि में एक दृश्य बनाना ठीक है, लेकिन आप कह रहे हैं कि यह नहीं है। क्यूं कर? –

+0

@iamataptool शायद आप 'init' विधि के साथ सुरक्षित रूप से UIView बना सकते हैं लेकिन 'initWithFrame:' विधि के साथ नहीं? – DanSkeel

+0

कैलियर टिप ने मेरा दिन और सप्ताह बनाया। आपका बहुत बहुत धन्यवाद! –

0

Drawing and Printing Guide कहता है:

महत्वपूर्ण UIKit कक्षाएं आम तौर पर सुरक्षित थ्रेड नहीं कर रहे हैं। सभी ड्राइंग से संबंधित संचालन आपके आवेदन के मुख्य धागे पर किया जाना चाहिए।

इस प्रकार, जैसा कि मैं इसे समझता हूं, ऐसा लगता है कि एकमात्र समस्या "ड्राइंग से संबंधित संचालन" से संबंधित है। अगर हम मानते हैं कि एक सही वर्ग केवल drawRect: विधि में इस तरह के ऑपरेशन को निष्पादित करता है, तो आपके द्वारा सुझाए गए दृष्टिकोण को ठीक होना चाहिए।

+0

मेरे मामले में, मेरा ऐप 'UIAplplicationLaunchOptionsLocalNotificationKey' के माध्यम से जागता है, इसलिए यह पृष्ठभूमि में है। क्या यह ठीक है, अगर ऐप पृष्ठभूमि में है तो मैं सबव्यूव परिवर्धन करता हूं? https://stackoverflow.com/questions/46584566/how-to-stop-handle-ui-operations-in-ios-when-app-moves-to-background-state – Nil

3

मैं एक चेतावनी प्राप्त करने के लिए एक्सकोड संस्करण 9.0 बीटा 3 (9 एम 174 डी) का उपयोग करता हूं।

[UView init] मुख्य थ्रेड से बुलाया जाना चाहिए केवल

तो मुझे लगता है कि आप मुख्य थ्रेड में यूआई बनाना चाहिए बेहतर

दिखाएँ नीचे चित्र:

enter image description here

संबंधित मुद्दे