2013-01-01 11 views
6

मैं कुछ कोर छवि फ़िल्टर को सबसे प्रभावी तरीके से चलाने की कोशिश कर रहा हूं। स्मृति चेतावनियों और दुर्घटनाओं से बचने की कोशिश कर रहा है, जो मुझे बड़ी छवियों को प्रस्तुत करते समय मिल रहा है। मैं ऐप्पल की कोर इमेज प्रोग्रामिंग गाइड देख रहा हूं। बहु-थ्रेडिंग के बारे में यह कहता है: "प्रत्येक थ्रेड को अपनी स्वयं की सीआईफ़िल्टर ऑब्जेक्ट्स बनाना चाहिए। अन्यथा, आपका ऐप अनपेक्षित रूप से व्यवहार कर सकता है।"आईओएस: कोर छवि और बहु ​​थ्रेडेड ऐप्स

इसका क्या अर्थ है?

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

//start HUD code here, on main thread 

// Get a concurrent queue form the system 
dispatch_queue_t concurrentQueue = 
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(concurrentQueue, ^{ 

    //Effect image using Core Image filter chain on a background thread 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     //dismiss HUD and add fitered image to imageView in main thread 

    }); 

}); 

अधिक एप्पल डॉक्स से:

थ्रेड सुरक्षा

CIContext और CIImage वस्तुओं को बनाए रखने के अपरिवर्तनीय हैं, जिसका मतलब है कि प्रत्येक सुरक्षित रूप से धागे के बीच साझा किया जा सकता है। कई धागे सीआईएममेज ऑब्जेक्ट्स को प्रस्तुत करने के लिए एक ही GPU या CPU CIContext ऑब्जेक्ट का उपयोग कर सकते हैं। हालांकि, यह CIFilter ऑब्जेक्ट्स का मामला नहीं है, जो परिवर्तनीय हैं। एक सीआईएफलेटर वस्तु को धागे के बीच सुरक्षित रूप से साझा नहीं किया जा सकता है। यदि आपका ऐप बहुप्रचारित है, तो प्रत्येक थ्रेड को अपना स्वयं का CIFILTER ऑब्जेक्ट बनाना होगा। अन्यथा, आपका ऐप अप्रत्याशित रूप से व्यवहार कर सकता है।

उत्तर

11

मुझे यकीन नहीं है कि यह अलग तरीके से कैसे कहें: प्रत्येक पृष्ठभूमि धागे को आपकी फ़िल्टर श्रृंखला में सीआईफ़िल्टर ऑब्जेक्ट्स का अपना संस्करण बनाना होगा। इसे प्राप्त करने का एक तरीका यह होगा कि आप dispatch_async(...) प्रत्येक पृष्ठभूमि ऑपरेशन के लिए अपनी फ़िल्टर श्रृंखला की एक प्रति बनाएं।

//start HUD code here, on main thread 
// Assuming you already have a CIFilter* variable, created on the main thread, called `myFilter` 
CIFilter* filterForThread = [myFilter copy]; 
// Get a concurrent queue form the system 
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(concurrentQueue, ^{ 
    CIFilter filter = filterForThread; 

    // Effect image using Core Image filter chain on a background thread 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     //dismiss HUD and add fitered image to imageView in main thread 

    }); 

}); 
[filterForThread release]; 

यहाँ क्या होता है कि filterForThreadmyFilter की एक प्रति है: कोड है कि आप इस तरह है कि कुछ लग सकता है तैनात हैं। आपके द्वारा dispatch_async पर जाने वाले ब्लॉक में filterForThread का संदर्भ देने से उस ब्लॉक को filterForThread बनाए रखने का कारण बन जाएगा, तो कॉलिंग स्कोप filterForThread जारी करता है, जो ब्लॉक को filterForThread के वैचारिक स्वामित्व के हस्तांतरण को प्रभावी ढंग से पूरा करता है (क्योंकि ब्लॉक केवल संदर्भ के साथ छोड़ा गया एकमात्र चीज़ है यह)। filterForThread को थ्रेड के लिए निजी के रूप में सोचा जा सकता है जहां ब्लॉक निष्पादित किया जाता है।

यह थ्रेड सुरक्षा आवश्यकताओं को पूरा करने के लिए पर्याप्त होना चाहिए।

+0

धन्यवाद। मैं आपके जवाब को कुछ दर्जन बार पढ़ूंगा और शायद यह डूब जाएगा :)। – Mrwolfy

+1

यहां एक समानता है: यदि आप एक पेपर लिख रहे थे, और आप 5 अलग-अलग लोगों को अपने लिए समीक्षा/संपादित करने के लिए चाहते थे (एक ही समय में), आप एक प्रिंट आउट नहीं करेंगे, इसके आसपास के 5 लोगों को रखेंगे, और आपके पास वे एक साथ संपादन करने की कोशिश करते हैं; आप 5 प्रतियां बनायेंगे, और प्रत्येक समीक्षक/संपादक को अपना स्वयं का दें। यहां वही विचार है। आप प्रत्येक थ्रेड को इसकी सीआईफ़िल्टर की प्रतिलिपि दे रहे हैं। – ipmcc

+0

ठीक है धन्यवाद। तुम्हारी सहायता सराहनीय है। – Mrwolfy

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