2017-04-05 8 views
8

मैं समेकन में थोड़ी गहरी डाइविंग कर रहा हूं और जीसीडी और NSOperation के बारे में बड़े पैमाने पर पढ़ रहा हूं। हालांकि, कैननिक answer on SO जैसी कई पोस्ट कई साल पुरानी हैं।2017/स्विफ्ट 3.1 - जीसीडी बनाम एनएसओपरेशन

यह मुझे लग रहा था कि NSOperation मुख्य लाभ कुछ प्रदर्शन की कीमत पर हो सकता है, प्रयोग किया है:

  • उच्चतम स्तर अमूर्त रूप में एक सरल प्रेषण से अधिक के लिए आम तौर पर "रास्ते जाने के लिए" (GCD के ऊपर बनाया गया)
  • कार्य में गड़बड़ी (रद्द करने, आदि) बहुत आसान
  • आसानी से कार्यों के बीच निर्भरता स्थापित करने के लिए बनाने के लिए

को देखते हुए GCD के DispatchWorkItem & ब्लॉक रद्द/विशेष रूप से DispatchGroup/qos, वहाँ वास्तव में एक प्रोत्साहन (मूल्य-प्रदर्शन वार) NSOperation अब जब यह क्रियान्वित करने के लिए शुरू किया मामलों में आप किसी कार्य को रद्द करने के लिए सक्षम होना चाहिए से अलग संगामिति के लिए उपयोग करने के लिए है या कार्य स्थिति पूछताछ?

ऐप्पल कम से कम अपने डब्ल्यूडब्ल्यूडीसी में जीसीडी पर बहुत अधिक जोर देता है (यह NSOperation से अधिक हालिया है)।

उत्तर

4

मैं उन्हें प्रत्येक का अपना उद्देश्य रखने के लिए देखता हूं। मैंने हाल ही में 2015 (डब्ल्यूडब्ल्यूडीसी) इस (उन्नत एनएसओपरेशंस) के बारे में बात की है, और मुझे यहां दो मुख्य बिंदु दिखाई देते हैं।

भागो समय & उपयोगकर्ता सहभागिता

बात से:

NSOperations से अधिक समय तक आप एक ब्लॉक को चलाने के लिए उम्मीद करेंगे एक छोटा सा के लिए चलाने के लिए, तो ब्लॉक आमतौर पर कुछ नैनोसेकंड ले, हो सकता है निष्पादित करने के लिए, अधिकांश मिलीसेकंड पर।

NSOperations, दूसरे हाथ पर, मिलीसेकंड की एक जोड़ी से बहुत लंबे समय तक, कहीं भी हो सकता है के लिए भी कई मिनट

उदाहरण वे के बारे में WWDC एप्लिकेशन है, जहां एक NSOperation वहां मौजूद है बात है कि उपयोगकर्ता में लॉग इन होने पर निर्भरता है। निर्भरता एनएसओपरेशन एक लॉगिन व्यू कंट्रोलर प्रस्तुत करता है और उपयोगकर्ता को प्रमाणीकृत करने की प्रतीक्षा करता है। एक बार समाप्त होने के बाद, एनएसओपरेशन खत्म हो जाता है और NSOperationQueue इसके काम को फिर से शुरू करता है। मुझे नहीं लगता कि आप इस परिदृश्य के लिए जीसीडी का उपयोग करना चाहते हैं।

उपवर्गीकरण

के बाद से NSOperations सिर्फ वर्ग हैं, आप उनमें से बाहर अधिक पुनर्प्रयोग पाने के लिए उन्हें उपवर्ग कर सकते हैं। जीसीडी के साथ यह संभव नहीं है।

उदाहरण: (ऊपर से WWDC लॉगिन परिदृश्य का उपयोग करना)

आपको लगता है कि एक उपयोगकर्ता बातचीत है कि उन्हें आवश्यकता है प्रमाणीकृत करने के साथ जुड़े रहे अपने कोड बेस में कई NSOperations है। (इस उदाहरण में, वीडियो को पसंद करना।) आप एक प्रमाणीकृत ऑपरेशन बनाने के लिए एनएसओपरेशन का विस्तार कर सकते हैं, फिर उन सभी एनएसओपरेशंस ने इस नई कक्षा का विस्तार किया है।

1

पहले, NSOperationQueue आप संचालन enqueue करते हैं, कि, एक start विधि, एक cancel विधि और कुछ नमूदार गुणों के साथ अतुल्यकालिक संचालन में किसी प्रकार का है, एक प्रेषण कतार के साथ एक एक ब्लॉक सबमिट कर सकते हैं या एक बंद या एक फ़ंक्शन एक प्रेषण कतार में, जिसे तब निष्पादित किया जाएगा।

एक "ऑपरेशन" मूल रूप से एक ब्लॉक (या बंद, कार्य) से मौलिक रूप से अलग है। एक ऑपरेशन में अंतर्निहित असीमित कार्य होता है, जबकि एक ब्लॉक (बंद या कार्य) बस यही होता है।

क्या एक NSOperation के पास आता है, हालांकि, एक अतुल्यकालिक समारोह, जैसे:

func asyncTask(param: Param, completion: (T?, Error?) ->()) 
अब वायदा साथ

हम जैसे ही अतुल्यकालिक समारोह को परिभाषित कर सकते हैं:

func asyncTask(param: Param) -> Future<T> 

जो इस तरह के असीमित कार्यों को काफी आसान बनाता है।

के बाद से वायदा map और flatMap और इतने पर की तरह Combinator कार्यों है, हम काफी आसानी से "अनुकरण" कर सकते हैं NSOperation की "निर्भरता" सुविधा, बस एक और अधिक शक्तिशाली और अधिक संक्षिप्त और अधिक सुबोध तरीके से।

हम भी कोड की कुछ लाइनें GCD पर आधारित के साथ NSOperationQueue किसी प्रकार लागू कर सकते हैं, का कहना है कि एक "कार्यपंक्ति" और मूल रूप से एक ही सुविधाओं के साथ, "maxConcurrentTasks" की तरह हैं और इसका उपयोग कार्य कार्यों enqueue कर सकते हैं (संचालन नहीं), बस एक और अधिक शक्तिशाली, अधिक संक्षिप्त और एक और समझदार तरीके से भी। ;)

रद्द करने योग्य ऑपरेशन प्राप्त करने के लिए, आपको NSOperation का उप-वर्ग बनाना होगा - जबकि आप एसिंक फ़ंक्शन "विज्ञापन-होड" - इनलाइन बना सकते हैं।

इसके अतिरिक्त, क्योंकि रद्द एक स्वतंत्र अवधारणा है, हम यह मान सकते हैं, कुछ पुस्तकालय जिसका कार्यान्वयन केवल GCD पर आधारित है, Uhm, हमेशा की तरह इस समस्या का हल मौजूद है;) यह इस तरह लग सकता है :

self.cancellationRequest = CancellationRequest() 
self.asyncTask(param: param, cancellationToken: cr.token).map { result in 
    ... 
} 

और बाद में:

override func viewWillDisappear(_ animated: animated) { 
    super.viewWillDisappear(animated) 
    self.cancellationRequest.cancel() 
} 

तो, IMHO वहाँ वास्तव में उपयोग करने के लिए कोई कारण नहीं है भद्दा NSOperation और NSOperationQueue, और कोई कारण नहीं उपवर्गीकरण के लिए किसी भी अधिक है NSOperation, जो कि काफी विस्तृत और आश्चर्यजनक मुश्किल है, जब तक कि आपको डेटा दौड़ की परवाह नहीं है।

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