2014-06-20 5 views
8

WWDC 2014 से उन्नत स्विफ्ट बात में, वक्ता जेनरिक का उपयोग कर एक समारोह memoizer के इस उदाहरण दिया memo var। क्या ज्ञात fibonacci फ़ंक्शन के प्रत्येक आमंत्रण के लिए एक मजबूत संदर्भ है? और यदि हां, तो आप उस स्मृति को कैसे जारी करेंगे जब आप इसके साथ काम करेंगे?लाइफटाइम closures

उत्तर

12

सी/ऑब्जेक्टिव-सी ब्लॉक शब्दावली में, memo एक __block चर (स्विफ्ट में, आप की जरूरत नहीं है है संदर्भ द्वारा चर कैप्चर करने के लिए स्पष्ट रूप से __block लिखें)। परिवर्तक को ब्लॉक (बंद) में निर्दिष्ट किया जा सकता है और सभी स्कॉप्स जो उस चर को देखते हैं, वे किसी अन्य चर से परिवर्तन देखेंगे (वे चर के संदर्भ को साझा करते हैं)। वेरिएबल तब तक वैध होगा जब तक कि कुछ ब्लॉक (बंद) जो इसका उपयोग करते हैं (इस मामले में केवल एक ब्लॉक है जो इसका उपयोग करता है) अभी भी जिंदा है। इसका उपयोग करने वाले अंतिम ब्लॉक के बाद हटा दिया जाता है, चर का दायरा समाप्त हो जाता है। यह कैसे काम करता है एक कार्यान्वयन विस्तार है।

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

एक आम तौर पर के बारे में कैसे __block में चिंता करने की जरूरत नहीं है चर आंतरिक रूप से काम करते हैं। लेकिन मूल रूप से, चर को सरलीकृत "ऑब्जेक्ट" प्रकार में लपेटा जाता है, वास्तविक "परिवर्तनीय" इस "ऑब्जेक्ट" का क्षेत्र होता है, जो संदर्भ गणना के माध्यम से स्मृति-प्रबंधित होता है। उन्हें छेड़छाड़ करने वाले ब्लॉक इस छद्म वस्तु वस्तु के लिए "मजबूत संदर्भ" रखते हैं - जब ढेर पर एक ब्लॉक बनाया जाता है (तकनीकी रूप से, जब उन्हें ढेर ब्लॉक से ढेर तक कॉपी किया जाता है) जो इस __block चर का उपयोग करता है, तो यह संदर्भ गणना को बढ़ाता है ; जब इसका उपयोग करने वाला एक ब्लॉक हटा दिया जाता है, तो यह संदर्भ गणना को कम करता है। जब संदर्भ संख्या 0 पर जाती है, तो यह छद्म-"ऑब्जेक्ट" हटा दिया जाता है, इसके परिवर्तनीय प्रकार के लिए उपयुक्त विनाशक का आह्वान किया जाता है।

अपने प्रश्न का उत्तर देने के लिए, "ज्ञात फाइबोनैकी फ़ंक्शन" एक ब्लॉक (बंद) है। और यह है कि memo चर के रखरखाव के लिए एक मजबूत संदर्भ है। "आमंत्रण" में मजबूत या कमजोर संदर्भ नहीं हैं; जब कोई फ़ंक्शन लागू होता है, तो यह उस संदर्भ का उपयोग करता है जिसमें फ़ंक्शन स्वयं होता है।memo वैरिएबल का जीवनकाल इस मामले में "ज्ञात फाइबोनैकी फ़ंक्शन" का जीवनकाल है, क्योंकि यह एकमात्र बंद है जो इस चर को कैप्चर करता है।

2

आंतरिक ब्लॉक (वापसी मूल्य) ज्ञापन को बनाए रखेगा जिसका अर्थ है कि ज्ञापन तब तक जारी रहेगा जब तक लौटा हुआ ब्लैक चारों ओर रखा जाता है।

मेमो का एक नया उदाहरण हर बार ज्ञापन समारोह कहलाता है। लौटाए गए ब्लॉक को कॉल करने से नए ज्ञापन उदाहरण नहीं बनेंगे।

लौटाई गई ब्लॉक को दायरे से बाहर होने पर स्मृति जारी की जाएगी।

3

memoize() का प्रत्येक आमंत्रण अन्य आमंत्रणों से स्वतंत्र, अपने memo चर बना देगा। यह तब तक रहता है जब तक कि बंद होने वाला संदर्भ बंद रहता है; जब बंद हो जाता है, तो इसके द्वारा कब्जा कर लिया गया चर (इस मामले में, memo) भी जारी किए जाते हैं।

आप इस स्यूडोकोड में की तरह एक struct लौटने की के रूप में इस के बारे में सोच सकते हैं:

struct Closure<T,U> 
{ 
    var memo: Dictionary<T, U> 
    func call(t: T): U 
    { 
     .... 
    } 
} 

func memoize<T: Hashable, U>(body: (T)->U) -> Closure<T,U> 
{ 
    return Closure(memo: Dictionary<T, U>()) 
} 
+0

यह कोड के समान नहीं है, क्योंकि एकाधिक बंदरगाह इस चर को कैप्चर कर सकते हैं, और चर सभी बंदियों के बीच साझा किया जाएगा। इसके अलावा परिवर्तनीय स्थिति को बंद करने के बाहर बंद करने और कोड के बीच भी साझा किया जाता है (यानी 'ज्ञापन' फ़ंक्शन में कोड सीधे 'ज्ञापन' भी पढ़ और लिख सकता है)। – newacct

+1

@newacct कोड इस विशेष मामले को चित्रित करना है, सामान्य रूप से बंद नहीं। – hamstergene

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