2009-11-14 13 views
9

वर्तमान विधि पारित होने के बाद मैं एक विधि निष्पादित करना चाहता हूं और यूआई अपडेट किया गया है। उस उद्देश्य के लिए, मैं अभी [object performSelector:@selector(someSelector) withObject:someObject afterDelay:0.0] का उपयोग कर रहा हूं। Apple's documentation के अनुसार, यह एक एनएसटीमर बनाता है जो तब चयनकर्ता को वर्तमान NSRunLoop में ट्रिगर और जोड़ देगा। लेकिन मैं इस बहुत ही सुरुचिपूर्ण पर विचार नहीं करता हूं। क्या कोको एक टाइमर इत्यादि के बिना, मौजूदा रन लूप में चयनकर्ता को सीधे एनक्यू करने का कोई आसान तरीका है?रन लूप के लिए चयनकर्ता को एन्क्यू करें - [NSObject प्रदर्शन चयनकर्ता: withObject: afterDelay:] जाने का तरीका?

performSelectorOnMainThread:withObject:waitUntilDone: (यदि मैं मुख्य धागे पर हूं) या performSelector:onThread:withObject:waitUntilDone:waitUntilDone:NO के साथ क्या मैं कम ओवरहेड के साथ चाहता हूं?

चियर्स और अग्रिम

MrMage

उत्तर

6

कोको में धन्यवाद घटना पर ही आधारित है। आप वर्तमान रन लूप के भीतर "चयनकर्ता को" संलग्न नहीं करते हैं। इसे सरलता से रखने के लिए: एप्लिकेशन (उपयोगकर्ता इनपुट, टाइमर, नेटवर्क गतिविधि ...) को भेजा गया एक ईवेंट रन लूप को चलाने का कारण बनता है, जिससे लूप के उस भाग में चीजें होती हैं। निश्चित रूप से "विवरण" हैं, लेकिन यह सबसे बुनियादी व्यवहार है।

यदि आप वर्तमान रन लूप के अंत में कुछ चयनकर्ता निष्पादित करना चाहते हैं, तो इसे अंतिम बार कॉल करें, या इसे लूप के आने वाले भाग (बहुत निकट) पर चलाने के लिए कहें। -परफॉर्म चयनकर्ता: ... विधियों ऐसा करने का सही तरीका है। वे एक टाइमर बनाते हैं जिसके परिणामस्वरूप ऐसी घटना होती है जो चीजों को घटित करती है।

अधिक जानकारी के लिए, Cocoa Event-Handling Guide देखें।

+1

मैंने जो दस्तावेज उद्धृत किया है, वह पढ़ता है 'वर्तमान थ्रेड पर निर्दिष्ट चयनकर्ता को निष्पादित करता है अगला रन लूप चक्र और वैकल्पिक देरी अवधि के बाद। ' इसका मतलब यह नहीं है कि किसी भी तरह चयनकर्ता को अगले रन लूप चक्र में लगाया जाना चाहिए? – MrMage

+0

निश्चित रूप से करता है। :-) टाइमर निकाल दिया घटना के माध्यम से Thats। –

+0

इसे स्वीकार किया क्योंकि यह मुझे वास्तव में क्या हो रहा है में सबसे अंतर्दृष्टि प्रदान करता है। – MrMage

4

मुझे -फॉर्मफॉर्मर के बारे में कुछ भी सुरुचिपूर्ण नहीं दिख रहा है: withObject: afterDelay: विधि जिसे आप हाइलाइट करते हैं। यह विधि रन लूप के वर्तमान चक्र को पूरा करने के बाद बस एक कार्य को निष्पादित करती है। documentation in the section you linked to से:

अगले रन पाश चक्र के दौरान और एक वैकल्पिक देरी अवधि के बाद वर्तमान धागे पर निर्दिष्ट चयनकर्ता करता है। क्योंकि यह चयनकर्ता को करने के लिए अगले रन लूप चक्र तक प्रतीक्षा करता है, इसलिए ये विधियां से स्वचालित मिनी विलंब प्रदान करती हैं जो वर्तमान में कोड निष्पादित करती है। एकाधिक कतारबद्ध चयनकर्ताओं को निष्पादित किया गया है ताकि वे कतारबद्ध हों।

एक NSTimer वस्तु इस का प्रबंधन करने के लिए बनाया नहीं है, चयनकर्ता बस एक निश्चित विलंब के बाद चलाने के लिए कतारबद्ध किया जाता है (एक छोटी सी देरी रन लूप चक्र के पूरा होने के तुरंत बाद का मतलब है)। यूआई के अपडेट के बाद आप जो कार्य करना चाहते हैं, उसके लिए यह सबसे सरल तकनीक है।

अधिक स्पष्ट, थ्रेडेड क्यूइंग के लिए, आप NSOperations और NSOperationQueues देख सकते हैं। एक maxOoncurrentOperationCount के साथ एक NSOperationQueue 1 के बाद एक ऑपरेशन चला सकता है।

+0

यह एक टाइमर बनाता है: http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelector : withObject: afterDelay: 'यह विधि वर्तमान थ्रेड के रन लूप पर एक चयनकर्ता संदेश करने के लिए टाइमर सेट करती है। टाइमर को डिफ़ॉल्ट मोड (NSDefaultRunLoopMode) में चलाने के लिए कॉन्फ़िगर किया गया है। जब टाइमर आग लगती है, तो धागा रन लूप से संदेश को हटाने और चयनकर्ता को निष्पादित करने का प्रयास करता है। ' – MrMage

+0

आप दोनों तरह के अधिकार हैं। -performSelector: withObject: afterDelay: कोर नींव टाइमर एपीआई का उपयोग करता है, न कि एनएसटीमर उदाहरण। – NSResponder

+1

बस उस समान दिखने को जोड़ना चाहता था [स्वयं प्रदर्शन चयनकर्ता: <#(SEL)#> ऑब्जेक्ट: <#(id)#>] रन लूप के अगले भाग तक प्रतीक्षा नहीं करता है लेकिन विधि को तुरंत कॉल करता है। यह स्पष्ट है लेकिन फिर भी मैं इसे वहां डाल रहा हूं। – SayeedHussain

2

मैं इस तकनीक को कई बार अपने आप का इस्तेमाल किया है, और मैं यह है कि असजीला ... हालांकि, एक वैकल्पिक आप की कोशिश कर सकते है नहीं लगता है:

performSelectorOnMainThread:withObject:waitUntilDone:NO

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

+0

मैंने अपने स्वयं के पोस्ट में इसके बारे में लिखा ... – MrMage

+0

हम्म, मेरी माफ़ी - मुझे लगता है कि अंत में मुझे याद आया। ऐसा करने का एक बेहतर तरीका है जो आप करना चाहते हैं। –

4

मैं NSRunLoop विधि को पसंद करता हूं "प्रदर्शन चयनकर्ता: लक्ष्य: तर्क: आदेश: मोड:"। यह रन लूप के अगले पुनरावृत्ति तक चयनकर्ता को निष्पादित करने की गारंटी नहीं है, और आपको मनमाने ढंग से देरी, आदि के साथ गड़बड़ करने की आवश्यकता नहीं है।

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

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