फ्रीज पर संकेत के बारे में अपने प्रश्न के दूसरे भाग के लिए:
जब एक कतार पर dispatch_sync
बुला, हमेशा सत्यापित करें कि इस कतार में पहले से ही वर्तमान कतार (dispatch_get_current_queue()
) नहीं है। क्योंकि dispatch_sync
आपके पैरामीटर को पहले पैरामीटर के रूप में पारित कतार पर कतारबद्ध करेगा, और फिर जारी रखने से पहले इस ब्लॉक को निष्पादित करने की प्रतीक्षा करेगा।
तो यदि dispatch_get_current_queue()
और जिस कतार पर आप अपने ब्लॉक को एनक्यू करते हैं, वही है, अर्थात् आपके मामले में मुख्य कतार है, मुख्य कतार प्रेषण_एसआईएनसी को कॉल पर अवरुद्ध कर देगी ... मुख्य कतार ब्लॉक को निष्पादित करने के रूप में, लेकिन ऐसा नहीं हो सकता है, क्योंकि कतार अवरुद्ध है, और आपके पास पर एक सुंदर डेडलॉक है।
एक समाधान ([संपादित करें] ऊपर iOS6 तक):
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_block_t block =^
{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationAuthenticationSuccess object:nil userInfo:ret];
};
if (dispatch_get_current_queue() == main)
block(); // execute the block directly, as main is already the current active queue
else
dispatch_sync(main, block); // ask the main queue, which is not the current queue, to execute the block, and wait for it to be executed before continuing
[संपादित करें] सावधान रहें, dispatch_get_current_queue()
केवल है डीबगिंग उद्देश्यों के लिए और उत्पादन में कभी नहीं इस्तेमाल किया जाएगा। वास्तव में, dispatch_get_current_queue
आईओएस 6.1.3 के बाद से हटा दिया गया है।
यदि आप मुख्य कतार (जो केवल मुख्य धागे से जुड़े हैं) के विशिष्ट मामले में हैं, तो आप इसके बजाय @ अर्थ-मामलों द्वारा सुझाए गए अनुसार [NSThread isMainThread]
का परीक्षण कर सकते हैं।
वैसे, क्या आप वाकई अपने मामले में dispatch_sync
करने की जरूरत है? मुझे लगता है कि थोड़ी देर बाद आपकी अधिसूचना भेजना, इसे भेजने तक ब्लॉक करने से परहेज करना आपके मामले में स्वीकार्य है, इसलिए आप dispatch_async
(dispatch_sync
का उपयोग करने और कतार तुलना की स्थिति की आवश्यकता के बजाय) का उपयोग करने पर भी विचार कर सकते हैं, जो डेडलॉक से बचें मुद्दा भी
क्योंकि आप मुख्य कतार पर एक ब्लॉक enqueuing रहे हैं यह deadlocking है - जो मुख्य थ्रेड पर है - और उस के लिए प्रतीक्षा करने के लिए मुख्य थ्रेड कह पूरा करने के लिए ब्लॉक। –
चूंकि आपने जो जवाब स्वीकार कर लिया है, वह उस कार्य को संबोधित नहीं करता है जिस पर आपने पूछा था, मैंने उस भाग को प्रश्न से हटा दिया है। डेडलॉकिंग प्रश्न का पहले से ही कई बार जवाब दिया गया है (और दस्तावेज़ों में भी है): http://stackoverflow.com/questions/7816159/dispatch-sync-on-main-queue-hangs-in-unit-test, http : //stackoverflow.com/questions/10315645/app-blocks-while-dipatching-a-queue, http://stackoverflow.com/questions/10984732/gcd-why-cant-we-use-a-dispatch-sync -ऑन-द-वर्तमान-कतार, लेकिन मैंने सोचा कि एक जीसीडी समारोह को रोकने के बारे में सवाल काफी दिलचस्प था। –
धन्यवाद।अगर मुझे पता था कि यह एक डेडलॉक मुद्दा था, तो मैं सवाल को सही तरीके से तैयार कर सकता था या Google को खोजकर समाधान ढूंढ सकता था। यह जानना अच्छा होगा कि dispatch_sync को कैसे दबाया जाए, लेकिन हो सकता है कि यह उचित समाधान न हो। – teubanks