2012-11-02 20 views
7

में मुख्य थ्रेड पर विधि को करने के लिए मैं इस _cmd चाल में आए _cmd का उपयोग करना:उद्देश्य सी

-(void)methodToBeRunOnMainThreadWithObj:(id)object { 
    if (![NSThread isMainThread) { 
     [self performSelectorOnMainThread:_cmd withObject:object] 
    } else { 
     // ... method body 
    } 
} 

इस एक विधि सुनिश्चित करने के लिए एक विश्वसनीय तरीका है मुख्य थ्रेड पर किया जाता है?

+0

क्या एक सुंदर चाल है! प्रतिबंधों को नोट करने के लिए टाइपएफ़ वैकल्पिक – Gerstmann

उत्तर

7

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

तुम सच में नहीं कर सकते फोन करने वाले का व्यवहार को बदलने के हैं, तो आप कोशिश कर सकते हैं निम्नलिखित:

-(void)methodToBeRunOnMainThreadWithObj:(id)object { 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // code goes here 
    }); 
} 

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

इस कोड में गैर-ऑब्जेक्ट प्रकारों (int आदि) के तर्कों के साथ सहायक विधियों का अतिरिक्त लाभ भी है। यह तर्कसंगत संख्याओं के साथ विधियों का भी समर्थन करता है, जबकि performSelector:withObject: और इसके भाई विधियां केवल सीमित संख्या में तर्कों का समर्थन करती हैं। विकल्प NSInvocation ऑब्जेक्ट्स सेट अप करना है और ये दर्द हैं।

ध्यान दें कि इसके लिए आपके प्लेटफ़ॉर्म पर ग्रांड सेंट्रल डिस्पैच (जीसीडी) की आवश्यकता है।

+0

+1। मैंने अपने उत्तर में रिटर्न टाइप इश्यू को नजरअंदाज कर दिया क्योंकि सवाल में मूल विधि एक 'शून्य' है, लेकिन ओपी एक सामान्य समाधान की तलाश में प्रतीत होता है, और 'प्रदर्शन चयनकर्ता' एक नहीं है। – justin

3

_cmd अग्रेषण ठीक है जब तक चयनकर्ता _cmd द्वारा निर्दिष्ट परिभाषा/हस्ताक्षर दस्तावेज़ में बताए से मेल खाता है, कोई "विधि एक महत्वपूर्ण वापसी मान नहीं होना चाहिए और प्रकार आईडी की एक एकल तर्क लेना चाहिए, या तर्क। "। यदि यह मेल नहीं खाता है, तो आपको अनिर्धारित व्यवहार मानना ​​चाहिए। और 110% सुरक्षित और अमूर्त मशीन का पालन करने के लिए, वापसी का प्रकार id (या कुछ objc-type) होना चाहिए, और नतीजे को एक स्वामित्व संदर्भ वापस नहीं करना चाहिए।

+1

+1 के लिए – yfrancis

+0

@yfrancis मैंने शुरुआत में वापसी प्रकार का उल्लेख करने से भी बचाया :) लेकिन मैंने इसके बारे में कुछ संपादन में जोड़ा। – justin