2013-01-17 28 views
15

अपडेट करने के लिए मुख्य बनाम पृष्ठभूमि धागा मैं जीसीडी और ब्लॉक के लिए नया हूं और इसमें अपना रास्ता आसान कर रहा हूं।जीसीडी - यूआईएममेज व्यू

पृष्ठभूमि: मैं एक UIScrollView ALAssetsLibrary प्रयोग करने के लिए एक आलसी दिनचर्या लोड हो रहा है पर काम कर रहा हूँ। जब मेरा UIScrollView लोड करता है तो मैं इसे अपने एलासेट्स के aspectRatioThumbnails के साथ पॉप्युलेट करता हूं और फिर उपयोगकर्ता स्क्रॉल करता है, इसलिए मैं वर्तमान में प्रदर्शित होने वाले एलासेट के fullScreenImage को लोड करने के लिए नीचे दी गई दिनचर्या को कॉल करता हूं। ऐसा लगता है कि काम करता है।

(यदि किसी को भी एक बेहतर आलसी लोड हो रहा है दिनचर्या एक टिप्पणी पोस्ट कृपया है। मैं सब पर मैं देखा है हो सकता है लगता है प्लस WWDC वीडियो पर वे खपरैल के साथ और अधिक सौदा करने लगते हैं या बहुत अधिक जटिलता की तुलना में मैं की जरूरत है)

मेरा प्रश्न : मैं fullScreenImage लोड हो रहा है संभाल करने के लिए एक पृष्ठभूमि के धागे का उपयोग करें और इसके पूर्ण होने पर मैं UIImageView पर लागू करने का मुख्य थ्रेड का उपयोग करें। क्या मुझे मुख्य धागे का उपयोग करने की आवश्यकता है? मैंने देखा है कि सभी UIKit अपडेट मुख्य थ्रेड पर होने की आवश्यकता है, लेकिन मुझे यकीन नहीं है कि यह UIImageView पर लागू होता है या नहीं। मैं सोच रहा था कि यह करता है, क्योंकि यह एक स्क्रीन तत्व है लेकिन तब मुझे एहसास हुआ कि मुझे बस पता नहीं था।

- (void)loadFullSizeImageByIndex:(int)index 
{ 
    int arrayIndex = index; 
    int tagNumber = index+1; 
    ALAsset *asset = [self.assetsArray objectAtIndex:arrayIndex]; 

    __weak typeof(self) weakSelf = self; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
     UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage]; 

     if ([weakSelf.scrollView viewWithTag:tagNumber] != nil){ 

      dispatch_async(dispatch_get_main_queue(), ^{ 

       if ([weakSelf.scrollView viewWithTag:tagNumber]!= nil){ 
        UIImageView * tmpImageView = (UIImageView*)[weakSelf.scrollView viewWithTag:tagNumber]; 
        tmpImageView.image = tmpImage; 
       } 
      }); 
     } 
    }); 
} 
+0

बनाने यह छवि प्रतिपादन है जब आप पृष्ठभूमि धागा में डाल के बिंदु पर मजबूत किया जा रहा है गैर शून्य के लिए जाँच करने के लिए हो सकता है? – iDev

+0

@ एसीबी: बस एक परीक्षण किया - हाँ, यह प्रस्तुत करता है लेकिन इसे मुख्य थ्रेड (जैसे मेरे उदाहरण कोड में) से कॉल करने से लगभग 5x धीमा है। –

+0

लेकिन UIView दस्तावेज़ के अनुसार, आप इसे मुख्य धागे में उपयोग करना चाहते हैं। मैंने उस भाग को मेरे उत्तर में दस्तावेज़ीकरण से पोस्ट किया था। – iDev

उत्तर

32

हाँ, आप मुख्य थ्रेड जब भी आप UIImageView को छू रहे हैं, या (जैसे जब पृष्ठभूमि धागे पर UIImage रों निर्माण के रूप में यदि उल्लेख नहीं किया,) किसी भी अन्य UIKit वर्ग का उपयोग करने की जरूरत है।

अपने वर्तमान कोड के बारे में एक टिप्पणी: आपको इसे उपयोग करने से पहले weakSelf को एक मजबूत स्थानीय चर में असाइन करने की आवश्यकता है। अन्यथा आपका सशर्त पास हो सकता है, लेकिन फिर weakSelf वास्तव में इसका उपयोग करने से पहले इसे निकाला जा सकता है। यह कुछ

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
    UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage]; 

    __strong __typeof__(weakSelf) strongSelf = weakSelf; 
    if ([strongSelf.scrollView viewWithTag:tagNumber] != nil){ 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      __strong __typeof__(weakSelf) strongSelf = weakSelf; 
      if ([strongSelf.scrollView viewWithTag:tagNumber]!= nil){ 
       UIImageView * tmpImageView = (UIImageView*)[strongSelf.scrollView viewWithTag:tagNumber]; 
       tmpImageView.image = tmpImage; 
      } 
     }); 
    } 
}); 

तकनीकी तौर पर की तरह आप क्योंकि आप केवल एक बार वहाँ अपसंदर्भन कर रहे हैं, पृष्ठभूमि कतार में पहले सशर्त में ऐसा करने की जरूरत नहीं है देखने के लिए होगा, लेकिन यह हमेशा एक अच्छा विचार अपने कमजोर स्टोर करने के लिए है निश्चित रूप से इसे छूने से पहले एक मजबूत चर में चर।

+0

कमजोर। बलवान। मेरा सिर घूम रहा है! मुझे लगता है कि मैं जो कह रहा हूं वह मुझे मिलता है। छोटे फॉलोअप: मुख्य कतार कॉल के लिए ब्लॉक में मैंने एक अतिरिक्त सशर्त में रखा है ताकि यह जांच सके कि आवश्यक टैग वाला कोई दृश्य मौजूद है या नहीं। बाद में मैं सोच रहा था कि मैं पहले की जांच के बाद अनावश्यक है। हालांकि यह गलत है, हां, क्योंकि यह संभव है (अगर मैं कुछ सबव्यू शफल कर रहा था) कि जब मुख्य कतार आग लगती है तो ** बाद में ** और पृष्ठभूमि कतार और पहली सशर्त से अलग होती है। (यहां नौसिखिया धागा उपयोगकर्ता) –

1

यदि आपको UIImageView में छवि प्रस्तुत करने की आवश्यकता है, तो आपको इसे मुख्य थ्रेड में करने की आवश्यकता है। यह तब तक काम नहीं करेगा जब तक कि आप इसे अपने क्यू में दिखाए गए मुख्य कतार में नहीं करते हैं। किसी यूआई प्रतिपादन के साथ ही मामला है।

if ([weakSelf.scrollView viewWithTag:tagNumber]!= nil){ 
    UIImageView * tmpImageView = (UIImageView*)[weakSelf.scrollView viewWithTag:tagNumber]; 
    tmpImageView.image = tmpImage; 
} 

प्रति Apple documentation के रूप में,

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

1

हां आपको मुख्य धागे का उपयोग करने की आवश्यकता है, क्योंकि किसी भी यूआई परिवर्तन को मुख्य धागे में करने की आवश्यकता है।

जीसीडी का उपयोग करने के लिए इसका उपयोग डिवाइस पर मल्टी कोर का लाभ लेने के लिए किया जाता है। मजबूत और कमजोर स्वयं के लिए के रूप में

मजबूत आत्म: क्या आप कोड में एक मजबूत स्वयं, के लिए चाहते हो सकता है

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
(<your class> *) *strongSelf = weakSelf; 
    UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage]; 

    if ([strongSelf.scrollView viewWithTag:tagNumber] != nil){ 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      if ([strongSelf.scrollView viewWithTag:tagNumber]!= nil){ 
       UIImageView * tmpImageView = (UIImageView*)[strongSelf.scrollView viewWithTag:tagNumber]; 
       tmpImageView.image = tmpImage; 
      } 
     }); 
    } 
}); 

कहते हैं कि तुम एक दृश्य है जो एक एपीआई कॉल करने के लिए है और यह समय लगता है, इसलिए आप किसी अन्य दृश्य पर वापस स्विच करते हैं लेकिन आप अभी भी छवि को डाउनलोड करना चाहते हैं, तो मजबूत का उपयोग करें क्योंकि ब्लॉक स्वयं का मालिक है ताकि छवि डाउनलोड हो।

कमजोर आत्म: आप के बाद से ब्लॉक किसी भी स्वयं का स्वामी नहीं है एक बार आप एक अलग दृष्टिकोण को स्थानांतरित तो कमजोर स्वयं का उपयोग डाउनलोड करने के लिए, छवि चाहते हैं इसके बाद के संस्करण की स्थिति में हैं।

0

यदि आप केविन बल्लार्ड द्वारा सुझाए गए कोड में मजबूत का उपयोग नहीं करेंगे तो यह कमजोर हो जाने के कारण दुर्घटना का कारण बन सकता है।

इसके अलावा एक अच्छा अभ्यास भी

strongSelf = weakSelf 

    if(strongSelf) 
    { 
     // do your stuff here 
    }