2011-03-02 19 views
10

में फास्ट एन्यूमरेशन वीएस एनएसईएन्यूमेरेटर मैंने इसे और अधिक देखा है, के बजाय nextObject: का उपयोग करके लूप में तेज गणना का उपयोग करना क्यों तेज़ है।उद्देश्य-सी

उत्तर

29

NSEnumerator संग्रहों पर गणना करने का पुराना तरीका है। इसमें गणना का प्रतिनिधित्व करने के लिए एक ऑब्जेक्ट बनाना शामिल है, फिर प्रत्येक एकल पुनरावृत्ति के लिए एक विधि को कॉल करना शामिल है। हालांकि यह कई सालों से पूरी तरह से सेवा योग्य था, यह बहुत कुशल नहीं है, क्योंकि इसमें कम से कम एक संदेश लूप के प्रत्येक पुनरावृत्ति के लिए भेजता है। NSFastEnumeration अधिक आधुनिक दृष्टिकोण है, जो अधिक कुशल गणना प्रदान करने के लिए मूल भाषा समर्थन प्रदान करता है। जिस तरह से यह हुड के तहत काम करता है वह यह एक संरचना बनाता है जो वर्तमान गणना स्थिति का प्रतिनिधित्व करता है और संग्रह पर -countByEnumeratingWithState:objects:count: पर बार-बार कॉल करता है। यह विधि objects आउट-पैरा में ऑब्जेक्ट्स की सी सरणी के साथ-साथ count आउट-पैरा में काउंटर देता है। यह कॉलर को सी सरणी पर फिर से चालू करने की अनुमति देता है। संक्षेप में, इसका मतलब वस्तुओं के प्रति खंड में एक संदेश कॉल है, जो संग्रह के आधार पर, सभी वस्तुओं को प्राप्त करने के लिए एक संदेश कॉल के रूप में उतना ही कुशल हो सकता है।

आप कोड

for (id obj in myArray) { 
    [obj doSomething]; 
} 

की तरह यह कुछ मोटे तौर पर

NSFastEnumerationState __enumState = {0}; 
id __objects[MAX_STACKBUFF_SIZE]; 
NSUInteger __count; 
while ((__count = [myArray countByEnumeratingWithState:&__enumState objects:__objects count:MAX_STACKBUFF_SIZE]) > 0) { 
    for (NSUInteger i = 0; i < __count; i++) { 
     id obj = __objects[i]; 
     [obj doSomething]; 
    } 
} 

वास्तविक इस्तेमाल किया चर के बराबर में संकलक द्वारा अनुवादित हो जाता है छिपे हुए हैं लगता है कि का एक सा है, और अधिकतम आकार है, तो ऑब्जेक्ट बफर का कार्यान्वयन-निर्भर भी है, लेकिन बुनियादी विचार वहां है। यह एक सीआर सरणी पर पुनरावृत्ति में एक obj-c संग्रह पर पुनरावृत्ति का अनुवाद करता है।

+7

... और 'enumerateObjectsUsingBlock:' जितना तेज़ (एनएसएआरएआरई) या काफी तेजी से होगा (एनएस डिक्शनरी मानों की गणना करते समय) तो तेज गणना .... – bbum

0
NSArray *array = something; 

सरणी = {{1,2}, {2,3}, {3,4}}

सरणी मतलब यह है कि सरणी की एक सरणी है। तो आप सभी सरणी और उनके मूल्यों तक कैसे पहुंच सकते हैं। हम इस तरह

for (int i = 0; i < array.count; i++) 
{ 
    NSArray x = [array objectAtIndex:i]; 
} 

या एक तेजी से enum इस

for(NSArray array2 in array) 
{ 
    // do what ever you want with this new array2. 
} 

इस तरह काम करता है एक नमूना उदाहरण है पाश के लिए उपयोग कर सकते हैं।
पीएस। मैं भूल गया कि सरणी कंसोल में कैसा दिखता है।

+1

यह सिर्फ वाक्य रचनात्मक-चीनी है, यह जवाब नहीं देता कि एक दूसरे की तुलना में तेज़ क्यों है। – shreyasva

+0

ओह क्षमा करें मैंने आपका पूरा प्रश्न नहीं पढ़ा। – Robin

2

यह एप्पल के कार्यान्वयन के रूप में ही नहीं है बल्कि यह समझने के लिए उपयोगी है।

- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state 
        objects: (id*)stackbuf 
        count: (NSUInteger)len 
{ 
    IMP nextObject = [self methodForSelector: @selector(nextObject)]; 
    int i; 

    state->itemsPtr = stackbuf; 
    state->mutationsPtr = (unsigned long*)self; 
    for (i = 0; i < len; i++) 
    { 
     id next = nextObject(self, @selector(nextObject)); 

     if (nil == next) 
    { 
     return i; 
    } 
     *(stackbuf+i) = next; 
    } 
    return len; 
}