2010-08-03 16 views
51

मैं अक्सर खुद को "उपयोगिता" कक्षाएं लिखता हूं जिसे मेरी परियोजनाओं में फिर से उपयोग किया जा सकता है।उद्देश्य सी: ब्लॉक बनाम चयनकर्ता बनाम प्रोटोकॉल

उदाहरण के लिए, मान लें कि मेरे पास "पता पुस्तिका" दृश्य है। मैं अपनी पता पुस्तिका का उपयोग यह चुनने के लिए कर सकता हूं कि कौन ईमेल भेजता है, या शायद मीटिंग अनुरोध में कौन जोड़ा जाता है।

मैं इस दृश्य नियंत्रक को विकसित करूंगा ताकि इसका उपयोग ईमेल नियंत्रक और मीटिंग नियंत्रक दोनों द्वारा किया जा सके, कॉलर तंत्र को किसी भी प्रकार के कॉलर तंत्र को उपयोगकर्ता को पता पुस्तिका को किसी को चुनने के लिए या तो समाप्त करने के लिए, या उन्होंने रद्द कर दिया।

ऐसा लगता है कि इस परिदृश्य में मूल रूप से चार (उचित) दृष्टिकोण हो सकते हैं;

  • पता पुस्तिका नियंत्रक पर एक "एड्रेसबुक डिलीगेट" प्रोटोकॉल और संबंधित प्रतिनिधि संपत्ति बनाएं। फिर परिणाम संवाद करने के लिए प्रोटोकॉल में परिभाषित संदेशों का उपयोग करें (UIActionSheetDelegate के समान)।

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

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

  • पताबुक नियंत्रक दो ब्लॉक पास करें; जब कोई उपयोगकर्ता एड्रेस बुक से किसी को चुनता है, और एक उपयोगकर्ता को अनुरोध रद्द करने पर चलाने के लिए चलाया जाता है।

ब्लॉक इतना काफी उपयोगी मेरे लिए किया गया है, और भी बहुत कुछ सुंदर, मैं अपने आप को लगभग जब उन्हें नहीं का उपयोग करने से अधिक उलझन में लग रहा हूँ।

मैं इस विषय पर उनके विचारों के साथ मदद करने के बजाय स्टैक ओवरफ्लो समुदाय के अधिक अनुभवी सदस्यों की उम्मीद कर रहा हूं।

+0

मुझे आशा है कि लोग किसी भी मौजूदा उत्तर के लिए वोट दें, जिनसे वे सहमत हैं। मैं कुछ दिनों में जो भी वोट देता हूं उसका जवाब दूंगा। – Steve

उत्तर

27

ऐसा करने का 'पारंपरिक' तरीका प्रोटोकॉल के साथ है। अनौपचारिक लोगों का इस्तेमाल @protocol भाषा में जोड़ा जाने से पहले किया गया था, लेकिन यह मेरे समय से पहले था और कम से कम पिछले कुछ वर्षों से अनौपचारिक प्रोटोकॉल को हतोत्साहित किया गया है, विशेष रूप से @ ओपशनल विनिर्देशक को दिया गया है। एक 'प्रतिनिधि' के लिए जो दो एसईएल पास करता है, यह औपचारिक प्रोटोकॉल घोषित करने की तुलना में अधिक बदसूरत लगता है, और आम तौर पर मेरे लिए सही नहीं लगता है। ब्लॉक बहुत नए हैं (आईओएस पर esp।), क्योंकि ये चीजें जाती हैं, और जब तक हमने अभी तक सबसे अच्छी कोशिश की और सही शैली पर दस्तावेज/ब्लॉग की जबरदस्त मात्रा को नहीं देखा है, मुझे यह विचार पसंद है, और ऐसा लगता है कि यह एक है चीजों के ब्लॉक सबसे अच्छे हैं: साफ नए नियंत्रण प्रवाह संरचनाएं।

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

[Controller askForSelection:^(id selection){ 
    //blah blah blah 
} canceled:^{ 
    //blah blah blah 
}]; 

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

+10

कृपया, कृपया, कृपया प्रति विधि एक ब्लॉक का उपयोग करें (और इसे अंतिम तर्क दें)। यदि आपको दो की आवश्यकता है, तो उस वर्ग को बनाएं जो 'em। कल्पना कीजिए कि क्या होगा यदि सभी ब्ला ब्ला ब्लाह पूरी तरह से फैले हुए थे। – bbum

+2

यदि आप इन्हें पास करने के लिए वैरिएबल में स्टोर करते हैं और ब्लॉक अक्षर का उपयोग नहीं करते हैं तो यह काफी खराब नहीं है। लेकिन हाँ, उन्हें अलग करना शैली के अनुसार बेहतर है। –

+14

@bbum - सभी उचित सम्मान के साथ (और मैं आपका बहुत सम्मान करता हूं) मुझे लगता है कि एक विधि प्रति विधि नियम पूरी तरह से स्टाइल पर आधारित है, और जिस तरह से दो ब्लॉक का उपयोग करना किसी और कथन से भी बुरा नहीं दिखता है । यदि आपको लगता है कि एक if-then कथन बदसूरत है, तो हाँ यह बदसूरत दिखाई देगा, क्योंकि [एस,] एस,^एस, और: एस के अलावा, यह एक और अन्य की तरह संरचित है। (यह भी एक ही विचार है कि हां (कि कुछ चुना गया था) तो इसके साथ कुछ करें, अगर इसके तहत ब्लॉक न करें।) –

16

मैं करूंगा है बस अपने पहले दृष्टिकोण के साथ जाओ। यह कोको में एक कोशिश की और सही पैटर्न है, और आप जो कर रहे हैं उसमें बहुत अच्छी तरह फिट बैठते हैं।

अन्य तरीकों पर कुछ टिप्पणियां:

  1. अनौपचारिक प्रोटोकॉल - मैं वास्तव में एक औपचारिक प्रोटोकॉल पर ऐसा करने का कोई भी लाभ नहीं दिख रहा। प्रत्येक औपचारिक प्रोटोकॉल @optional विधियों के बाद से, अनौपचारिक प्रोटोकॉल की उपयोगिता बहुत कम है।
  2. पासिंग एसईएल - मुझे नहीं लगता कि यह कोको में एक स्थापित पैटर्न है। मैं व्यक्तिगत रूप से प्रतिनिधि दृष्टिकोण से बेहतर नहीं मानता, लेकिन यदि यह आपकी सोच को बेहतर तरीके से फिट करता है, तो इसके लिए जाएं। आप वास्तव में राज्य से छुटकारा नहीं पा रहे हैं; आप बस कुछ और में बदल रहे हैं। व्यक्तिगत रूप से, मैं एक ivar रखना पसंद करूंगा कि मैं चयनकर्ता प्रकारों का उपयोग किए बिना सेट और जांच कर सकता हूं।
  3. पासिंग ब्लॉक - यह एक नए आयु के दृष्टिकोण की तरह है, और इसमें कुछ योग्यता है। मुझे लगता है कि आपको सावधान रहना चाहिए क्योंकि मेरी राय में, यह वास्तव में अच्छी तरह से स्केल नहीं करता है। उदाहरण के लिए, यदि एनएसटीबल व्यू के प्रतिनिधि और डेटा स्रोत विधियां सभी ब्लॉक थीं, तो मैं व्यक्तिगत रूप से कुछ हद तक परेशान हूं। कल्पना करें कि क्या आप 10 अलग-अलग ब्लॉक सेट करना चाहते हैं, तो आपकी -awakeFromNib (या जो कुछ भी) विधि बहुत बड़ी होगी। इस मामले में व्यक्तिगत तरीके अधिक उपयुक्त लगती हैं। हालांकि, अगर आप सुनिश्चित हैं कि आप कभी भी आगे नहीं जा रहे हैं, तो दो विधियों का कहना है, तो ब्लॉक दृष्टिकोण अधिक उचित लगता है।
संबंधित मुद्दे