2011-10-24 10 views
12

क्षमा करें, मुझे यहां सही भाषा का यकीन नहीं है, लेकिन जब विधियों को बुलाया जाता है क्योंकि वे या तो प्रतिनिधि विधियां हैं, या पर्यवेक्षक के लक्ष्य के रूप में सूचीबद्ध होने के परिणामस्वरूप बुलाए गए तरीकों को, वे मुख्य धागे पर निष्पादित किए जाते हैं ? जॉनआईओएस मुख्य धागे पर निष्पादित प्रतिनिधियों और पर्यवेक्षकों द्वारा बुलाए गए तरीके हैं?

उत्तर

9

प्रतिनिधियों यह भिन्न हो सकते हैं के लिए:

मैं अगर मैं सिर्फ इन तरीकों में यूआई परिवर्तन कर सकते हैं, या मैं उन्हें

dispatch_async(dispatch_get_main_queue(), ^{ UI stuff }); 

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

अधिसूचनाओं के लिए मुझे लगता है कि आप यह छोटा स्निप चाहते हैं।

एक अधिसूचना केंद्र पर्यवेक्षकों को समकालिक रूप से अधिसूचनाएं प्रदान करता है। दूसरे शब्दों में, पोस्ट नोटिफिकेशन: सभी पर्यवेक्षकों को अधिसूचना प्राप्त होने और संसाधित होने तक विधियां वापस नहीं आती हैं। नोटिफिकेशन को असंकालिक रूप से NSNotificationQueue का उपयोग करने के लिए। एक बहुप्रचारित आवेदन में, नोटिफिकेशन हमेशा उस थ्रेड में वितरित किया जाता है जिसमें अधिसूचना पोस्ट की गई थी, जो एक ही थ्रेड नहीं हो सकता है जिसमें एक पर्यवेक्षक स्वयं पंजीकृत होता है

से http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html

और अंत में KVO के लिए, सूचनाएं अन्य धागे से में आ सकते हैं। यहां एक ऐप्पल इंजीनियर को संभालने के बारे में क्या कहना है।

http://lists.apple.com/archives/cocoa-dev/2007/May/msg00022.html

+0

इसके अलावा NSURLConnection के लिए प्रतिनिधि कॉलबैक धागा कि अतुल्यकालिक लोड ऑपरेशन है, जो मुख्य थ्रेड होने की जरूरत नहीं है शुरू कर दिया पर हैं। – progrmr

+1

यह सुनिश्चित करें कि अच्छा होगा यदि डॉक्स इस स्पष्ट कर दिया होगा, लेकिन उदाहरण के लिए, UIImagePickerControllerDelegate प्रोटोकॉल संदर्भ भी शब्द 'धागा' का उपयोग नहीं करता। मैं किसी भी मुद्दे imagePickerController साथ नहीं देखा है: didFinishPickingMediaWithInfo :, लेकिन मैं अचानक सूत्रण मुद्दों के प्रति अधिक जागरूक होना है। आपकी स्निप अधिसूचनाओं के लिए निश्चित रूप से सहायक थी, जिसका उपयोग मैं अपने ऐप में करता हूं। फिर, मेरे नए थ्रेड-जागरूकता ने मुझे उनके बारे में सोचने लगा। मुझे यह सुनिश्चित करने के लिए सभी को जाना होगा कि वे सभी सही हैं। धन्यवाद! – John

+0

आप मान सकते हैं कि यूआई ऑब्जेक्ट्स के साथ प्रतिनिधि हमेशा मुख्य धागे पर होते हैं। दस्तावेज़ निर्दिष्ट करेंगे कि कोई अपवाद है, जिसे मैंने कभी नहीं देखा है। आप यहां दस्तावेज़ों से इसका अनुमान लगा सकते हैं। http://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/UIView/UIView.html#//apple_ref/doc/uid/TP40006816-CH3-SW147 – logancautrell

8

के रूप में कहा गया है, धागा फोन करने वाले के आधार पर भिन्न होगा। आपका प्रतिनिधि विधि में, यदि आप अनुकूलित करने की आवश्यकता है, तो आप हमेशा कुछ इस तरह कर सकते हैं:

if ([NSThread isMainThread]) { 
    // do the UI stuff as normal 
} else { 
    dispatch_async(dispatch_get_main_queue(), ^{ UI stuff }); 
} 
+0

यदि मैं वर्तमान धागे की जांच नहीं करता और हमेशा असीमित रूप से प्रेषित करता हूं तो क्या अंतर होगा? तो अगर उस प्रतिनिधि विधि को मुख्य धागे पर भी बुलाया जाता है, तो मैं प्रेषण कर रहा हूं, इसका क्या असर है? या इस समाधान के पेशेवर क्या हैं (वर्तमान धागे की जांच)? –

+1

मुझे नहीं लगता कि dispatch_async करने में कोई हानि होगी, भले ही यह पहले से ही मुख्य धागे पर हो। आपको यह सुनिश्चित करने के लिए प्रयोग करना होगा कि dispatch_async विधि का प्रदर्शन जुर्माना एनएसटीएचड की जांच करने से कहीं ज्यादा बदतर नहीं है MainThread संपत्ति है। –

3

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

जब तक प्रतिनिधि प्रतिनिधि प्रोटोकॉल दस्तावेज में स्पष्ट रूप से निर्दिष्ट नहीं किया गया है, प्रतिनिधि पैटर्न में एक विधि को उसी थ्रेड में सीधे कॉल किया जाता है जिसे कॉलर कॉल के पल में चल रहा है। जैसे अगर फोन करने वाले (सौंपने वस्तु) अपने प्रतिनिधि को फोन करना चाहता है और वर्तमान में पर "थ्रेड -1" चल रहा है तो कॉल एक ही धागे में क्या होगा:


// this is running in "Thread-1" --> then aDelegateMethod will continue on "Thread-1" 
[myDelegate aDelegateMethod] 

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

अंत में NSNotificationCenter आधारित तंत्र उसकी सूचनाएं एक ही धागे जहां मूल अधिसूचना नियुक्त किया गया है द्वारा कहा जाता है देखता है। यह ऐप्पल दस्तावेज में स्पष्ट रूप से कहा गया है (और यह कहना उचित है कि प्रत्येक धागे की अपनी अधिसूचना कतार है)।

तो सभी मामलों में धागा बनाए रखा है और यदि आप सुनिश्चित करें कि आपके यूआई ब्लॉक मुख्य कतार में कहा जाता है होना चाहता हूँ तो GCD कॉल है कि आप अपने प्रश्न में पोस्ट का उपयोग करें।

+0

अपनी आखिरी वाक्य दो: यह इस मुद्दे से निपटने का सबसे आसान तरीका है। मैं अभी अपने कोड से गुजर चुका हूं और सुनिश्चित किया है कि मैं इसे सभी मामलों में करता हूं। मैं इस मुद्दे पर भाग गया क्योंकि मेरा ऐप पृष्ठभूमि थ्रेड पर एक वीडियो बनाता है। वीडियो बनाते समय मैं अपने यूआई पर एक बटन को अक्षम करना चाहता था, लेकिन इससे कुछ गिलहरी व्यवहार हुआ। इससे बदले में थ्रेडिंग मुद्दों के बारे में मेरी नई जागरूकता बढ़ जाती है :-) – John

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