2011-02-07 10 views
9

क्या यह आमतौर पर -[NSRunLoop runUntilDate:] पर कॉल करने का अच्छा विचार है? यह किसी भी मुद्दे के बिना काम करता प्रतीत होता है, लेकिन यह मुझे रन लूप के भीतर से चलाने के लिए रन लूप को बताने में परेशान करता है।कॉल कर रहा है - [NSRunLoop runUntilDate:] एक अच्छा विचार है?

और जानकारी:

मैं एक परियोजना अभी है कि एक बाकी सेवा से डेटा प्राप्त करने में किया जाता है। जानकारी का एक महत्वपूर्ण टुकड़ा जिसे प्राप्त करने की आवश्यकता है वह मान्य डेटा वाले तिथियों की सीमा है। यह बहुत छोटा डेटा है जिसे केवल एक बार प्राप्त करने की आवश्यकता है, इसलिए मैंने फैसला किया कि इसे संभालने का सबसे अच्छा तरीका यह है कि यदि स्थानीय चर nil है तो संपत्ति डेटा डाउनलोड करें। मैं ASIHTTPRequest और ASINetworkQueue का उपयोग कर रहा हूं, इसलिए डिफ़ॉल्ट रूप से सबकुछ असीमित है, और इसके लिए काम करने के लिए, यह संपत्ति तब तक वापस नहीं आ सकती जब तक डेटा डाउनलोड और संसाधित नहीं हो जाता है। यहाँ मेरी कोड की एक रूपरेखा है, चर के नाम मासूम की रक्षा करने के लिए बदल दिया गया है:

__block BOOL isWorking = YES; 
__block ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:/*actual URL*/] autorelease]; 
[request setCompletionBlock:^{ 
    // set local variable 
    isWorking = NO; 
}]; 
[request setFailedBlock:^{ 
    // show alert to user 
    isWorking = NO; 
}]; 
[queue addOperation:request]; 

while (isWorking) { 
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 
} 

फिर, यह काम करने ठीक लग रहा है। क्या इस दृष्टिकोण का उपयोग करने के साथ कोई संभावित समस्या है?

उत्तर

3

आपको यह सुनिश्चित करना होगा कि किसी भी विधि से ऐसा न करें जिसे आप चल रहे लूप द्वारा बुलाया जा सकता है, जब तक ओवरलैपिंग कॉल पेड़ पूरी तरह से पुन: प्रवेश नहीं कर लेता है।

कोको टच यूआई कोड को पुनः प्रवेशकर्ता के रूप में दस्तावेज नहीं किया गया है (वास्तव में, ऐप्पल डीटीएस से चेतावनी/संकेत हैं जो यह नहीं है), इसलिए यदि आपका fetch डेटा हैंडलर किसी भी तरीके से यूआई विधि द्वारा बुलाया जा सकता है (या अन्य गैर-पुनर्विक्रेता कोड जिन्हें यूआई रन लूप में बुलाया जा सकता है), यूआई रन लूप को अंदर से बुलाकर इसकी अनुशंसा नहीं की जाती है।

+0

इसलिए, इस मामले में, यह इस दृष्टिकोण की तरह सुरक्षित है लगता है कि कह सकते हैं और कुछ नहीं है के बाद से यह संपत्ति डेटा डाउनलोड करने में व्यस्त है। लेकिन अगर ऐसी स्थिति थी जहां उपयोगकर्ता व्यस्त था, तो वह बटन दबा सकता था और उस संपत्ति को फिर से बुला सकता था, तो यह उड़ाएगा? जानकार अच्छा लगा। –

+0

क्या यह संपत्ति किसी भी यूआई विधि या प्रतिनिधि द्वारा प्रत्यक्ष या अप्रत्यक्ष रूप से उपयोग की जाती है? यदि हां, तो यह अभी भी एक बड़ी समस्या है। – hotpaw2

+0

मुझे यकीन है कि यह केवल तब ही इस कोड को दबाएगा जब ऐप शुरू में यूआई से पहले लोड हो जाता है, उपयोगकर्ता को भी प्रस्तुत किया जाता है। उसके बाद, डेटा वहां होगा और यह स्थानीय चर का उपयोग करेगा। यदि यह किसी कारण से डेटा डाउनलोड नहीं कर सकता है, तो यह उपयोगकर्ता को एक मोडल अलर्ट प्रदर्शित करता है और जब तक यह सफलतापूर्वक डाउनलोड नहीं होता है तब तक वे ऐप में नहीं जा सकते। –

4

क्या किसी प्रकार का स्पिनर प्रदर्शित करना बेहतर नहीं है और नेटवर्किंग कोड से एसिंक पूर्ण होने की घटनाओं के जवाब में इसे फाड़ना बेहतर नहीं है? पसंद:

[self displayLoadingSpinner]; 
[request setCompletionBlock:^{ 
    [self handleSuccess]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self hideLoadingSpinner]; 
    }]; 
}]; 
[request setFailedBlock:^{ 
    [self handleFailure]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self hideLoadingSpinner]; 
    }]; 
}]; 
[queue addOperation:request]; 

मैं इसे रन लूप के साथ बंदर से बेहतर मानता हूं। लेकिन यह हो सकता है कि आप इसे पहले से ही जानते हैं और सिर्फ यह जानना चाहते हैं कि रनलोप समाधान में क्या सटीक कमीएं हैं?


आप जब तक मूल्य के लिए तैयार है ब्लॉक करना चाहते हैं, तो आप एक सेमाफोर का उपयोग कर सकते हैं:

dispatch_semaphore_t sem = dispatch_semaphore_create(0); 
[request setCompletionBlock:^{ 
    dispatch_semaphore_signal(sem); 
}]; 
[queue addOperation:request]; 

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); 
dispatch_release(sem); 
+0

यह वह दृष्टिकोण है जो मैं लेता हूं यदि एक प्रतिनिधि/कॉलबैक विधि दृष्टिकोण संभव था। इस मामले में, मुझे संपत्ति से वापस आने से पहले सेट करने के लिए मूल्य की आवश्यकता है या अन्यथा खराब डेटा के साथ आवेदन जारी रहेगा। मैं कोड को दोबारा कर सकता हूं ताकि डिजाइन पैटर्न काम करेगा। यह प्रश्न वास्तव में यह पता लगाने के बारे में है कि मेरे दृष्टिकोण के साथ कोई अप्रत्याशित समस्या हो सकती है जिसे मैं अभी तक नहीं देख रहा हूं। –

+0

सैमफोर दृष्टिकोण मुख्य धागे को अवरुद्ध नहीं करेगा? क्या ब्लॉक को निष्पादित करने से रोका नहीं जाएगा? –

+0

यह इस बात पर निर्भर करता है कि आपके द्वारा उपयोग की जाने वाली HTTP लाइब्रेरी को कैसे कार्यान्वित किया जाता है।हां, मुख्य धागा अवरुद्ध होगा, ताकि यदि पुस्तकालय मुख्य धागे का उपयोग करता है, तो आप सेमफोर का उपयोग नहीं कर सकते हैं। – zoul

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