EnumerateObjectsUsingBlock के लिए BOOL * स्टॉप तर्क क्या है: के लिए उपयोग किया जाता है?


87

मैं enumerateObjectsUsingBlock:अपनी तेजी से गणना की जरूरत के लिए हाल ही में एक बहुत का उपयोग कर रहा हूँ, और मैं एक कठिन समय BOOL *stopमें गणना ब्लॉक के उपयोग को समझ रहा हूँ ।

NSArrayवर्ग संदर्भ राज्यों

stop: एक बूलियन मान का संदर्भ। ब्लॉक YESसरणी की आगे की प्रक्रिया को रोकने के लिए मान सेट कर सकता है । stopतर्क से बाहर ही तर्क है। आपको कभी भी इस बूलियन को YESब्लॉक के भीतर सेट करना चाहिए ।

तो फिर निश्चित रूप से मैं गणना को रोकने के लिए अपने ब्लॉक में निम्नलिखित जोड़ सकता हूं:

if (idx == [myArray indexOfObject:[myArray lastObject]]) {
    *stop = YES;
}

जो मैं बताने में सक्षम हूं, उससे स्पष्ट रूप *stopसे YESकोई नकारात्मक प्रभाव नहीं पड़ता है। एन्यूमरेशन अपने आप को एरे के अंत में अपने आप बंद हो जाता है। तो क्या *stopवास्तव में एक ब्लॉक में उपयोग करना आवश्यक है?

जवाबों:


156

stopब्लॉक का तर्क आपको समय से पहले गणना को रोकने की अनुमति देता है । यह breakएक सामान्य forलूप के बराबर है । यदि आप सरणी में प्रत्येक वस्तु से गुजरना चाहते हैं तो आप इसे अनदेखा कर सकते हैं।

for( id obj in arr ){
    if( [obj isContagious] ){
        break;    // Stop enumerating
    }

    if( ![obj isKindOfClass:[Perefrigia class]] ){
        continue;    // Skip this object
    }

    [obj immanetizeTheEschaton];
}

[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if( [obj isContagious] ){
        *stop = YES;    // Stop enumerating
        return;
    }

    if( ![obj isKindOfClass:[Perefrigia class]] ){
        return;    // Skip this object
    }

    [obj immanentizeTheEschaton];
}];

यह एक आउट पैरामीटर है क्योंकि यह कॉलिंग स्कोप से एक चर का संदर्भ है। इसे आपके ब्लॉक के अंदर सेट करने की आवश्यकता होती है, लेकिन इसके अंदर पढ़ा जाता है enumerateObjectsUsingBlock:, उसी तरह NSErrorआमतौर पर फ्रेमवर्क कॉल से आपके कोड में वापस भेज दिया जाता है।

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
    // N.B: This is probably not how this method is actually implemented!
    // It is just to demonstrate how the out parameter operates!

    NSUInteger idx = 0;
    for( id obj in self ){

        BOOL stop = NO;

        block(obj, idx++, &stop);

        if( stop ){
            break;
        }
    }
}

21
ध्यान दें कि stopझंडा सलाहकार है; गणना समवर्ती मामले में पुनरावृत्तियों की कुछ अपरिभाषित संख्या के लिए जारी रह सकती है, उदाहरण के लिए। यानी आप __blockएन्यूमरेशन के माध्यम से प्रत्येक पास पर बिना शर्त के एक चर सेट नहीं कर सकते हैं और यह उम्मीद करते हैं कि यह stopजल्दी समाप्त होने पर "अंतिम" मान होगा । आपको सेटिंग के साथ हमेशा "नहीं, इस ऑब्जेक्ट का उपयोग करें" करना चाहिए stop = YES;
bbum

@bbum, क्या आप स्पष्ट कर सकते हैं कि क्या निरंतर व्यवहार केवल समवर्ती गणन पर लागू होता है ? हालांकि यह उस मामले में पूरी तरह से समझने योग्य है, यह प्रलेखित नहीं है, और "धारावाहिक" गणना के लिए गधे में काफी आश्चर्यजनक काटने वाला होगा।
jscs

4
<rdar: // problem / 15015199> अब स्पष्टीकरण मांगता है क्योंकि दस्तावेज़ीकरण किसी भी तरह से नहीं कहता है और इसे करना चाहिए।
bbum
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.