2011-08-08 12 views
5

तो मेरे पास यह कोड है:dispatch_async कहीं कहीं अंतराल है, जहां नहीं मिल सकता है। क्या एनएसएलओजी समस्या है?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ 

//Bunch of code 

NSLog(@"Test"); 

}); 

जो चलाता है और तुरंत nslog देता है। लेकिन कोड के परिणाम केवल कुछ सेकंड में देरी स्क्रीन पर दिखाई देते हैं। क्या एनएसएलओएल का उपयोग यहां किया जा रहा है, जिसका मतलब है कि इसे आमतौर पर पहले कहा जाता है, जब यह वास्तव में नहीं होता है तो यह तेज़ी से प्रतीत होता है। मैं उलझन में हूं कि यह देरी कहां से आ रही है, क्योंकि एनएसएलओजी तब चलने वाले सभी कोड के अंत में सही है।

इसके अलावा, मेरी समस्या का एक और समाधान, क्या एनएसएलओजी प्राप्त करना संभव है जब हर विधि को कहा जाता है (एनएसजेम्बीज की तरह थोड़ा मुझे लगता है) तो मैं सुनिश्चित कर सकता हूं कि कुछ ऐसा नहीं है जिसे मैंने नहीं देखा मेरे ऐप के मीठे प्रतिक्रिया समय को ऊपर?

+3

आप अपने लॉग को तत्काल क्यों दिखाना चाहते हैं? आपके "कोड का गुच्छा" चलाने में कुछ सेकंड लग सकते हैं, उसमें लॉग में देरी हो सकती है, क्योंकि यह आपके शेष ब्लॉक के कोड के बाद ही निष्पादित होगा। –

+0

यह मुझे भ्रमित करता है। यह कोड के हर बिट के बाद है, और फिर भी स्क्रीन पर परिणाम दिखाने के लिए कुछ सेकंड लगते समय तुरंत दिखाई देता है। – Andrew

+1

ठीक है, तो आप कह रहे हैं कि एनएसएलओजी कथन का कंसोल पर तुरंत अपना टेक्स्ट दिखाया गया है, लेकिन आपके "कोड का गुच्छा" इसमें अन्य यूआई अपडेट हैं जो तुरंत स्क्रीन पर प्रभावी नहीं होते हैं?यदि ऐसा है, तो वे किस प्रकार के यूआई अपडेट हैं? क्या वे मुख्य धागे पर असीमित रूप से प्रेषित हैं? क्या इस प्रक्रिया को प्रेषित करने के बाद मुख्य धागे पर एक तंग पाश में पकड़ा जा सकता है, संभावित रूप से यूआई अपडेट को रोक रहा है? –

उत्तर

11

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

आप क्या करना है अपने ब्लॉक कतार अंदर इस तरह यूआई धागा में अपने चित्रमय अद्यतन है:

dispatch_async(dispatch_get_main_queue(), ^{ 
     // Do GUI stuff. 
    }); 

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

dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.somewidget setNeedsDisplay]; 
     [self.view setNeedsDisplay]; 
     [self.dontforgetme setNeedsDisplay]; 
    }); 
के साथ "मेरे एप्लिकेशन की मीठी प्रतिक्रिया समय लेने एप्लिकेशन" अपने से संबंध

, ऐसा लगता है कि आप कर रहे हैं उपयोगकर्ता इंटरफ़ेस को अवरुद्ध करने से बचने के लिए जीडीसी का उपयोग करने की कोशिश कर रहा है।

/// Stick this in code you want to assert if run on the main UI thread. 
#define DONT_BLOCK_UI() \ 
    NSAssert(![NSThread isMainThread], @"Don't block the UI thread please!") 

/// Stick this in code you want to assert if run on a background thread. 
#define BLOCK_UI() \ 
    NSAssert([NSThread isMainThread], @"You aren't running in the UI thread!") 

के रूप में: प्रोग्राम के सुनिश्चित करें कि आप यूआई सूत्र में सीपीयू गहन आपरेशन करने के लिए नहीं होता है, और इसके विपरीत, आप यूआई ब्लॉक में जीयूआई अद्यतन चलाने के लिए, मैं अपने आप को निम्नलिखित मैक्रो बनाया है आप टिप्पणियों से देख सकते हैं, मैं उन मैक्रोज़ का उपयोग उन तरीकों की शुरुआत में करता हूं जिन्हें मैं सुनिश्चित करना चाहता हूं कि मैं गलत जगह पर त्रुटि से उपयोग नहीं कर रहा हूं। मैंने इन मैक्रोज़ और अधिक यादृच्छिक सामान https://github.com/gradha/ELHASO-iOS-snippets पर रखे हैं जिन्हें आप उपयोगी पा सकते हैं।

11

UIKit थ्रेड-सुरक्षित नहीं है। आपके यूआई को प्रभावित करने वाली कोई भी कॉल मुख्य थ्रेड पर बनाई जानी चाहिए, या आपको अजीब, अप्रत्याशित व्यवहार मिलेगा। उदाहरण:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    // Background code that doesn't need to update the UI here 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     // UI code here 
    }); 
}); 
+0

यह एक अच्छा जवाब है क्योंकि मुझे लगता है कि इस तरह की अधिकांश घटना-प्रतिक्रिया कार्य होने की आवश्यकता है: मुख्य कतार से एक वर्कर कतार (अनिवार्य रूप से) तक फ़्लिप करें और फिर किसी भी UIKit कोड (जितना संभव हो उतना छोटा) के लिए मुख्य कतार में वापस आएं । यह कोड भी प्रासंगिक है, मुझे लगता है: http://stackoverflow.com/a/8186206/8047 –

+0

क्षमा करें, मैंने जो जवाब फिर से लिंक किया है उसे पढ़ें: यदि आप मुख्य धागे में एसिंक भेज रहे हैं, तो आपके पास नहीं है चिंता करने के लिए यदि आप पहले स्थान पर मुख्य धागे पर हैं। –

+0

इसे सही उत्तर के रूप में स्वीकार किया जाना चाहिए। धन्यवाद! – NSAddict

-1

इसके बजाय // कोड का गुच्छा का उपयोग करके, आपको वास्तविक कोड पेस्ट करना चाहिए, अन्यथा आपकी समस्या को ढूंढना और अपना समय बर्बाद करना मुश्किल है। मुझे लगता है कि आप शायद "कोड के गुच्छा" में ui को अपडेट करते हैं जो मुख्य धागे में होना चाहिए।

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