कोई सीधा जवाब नहीं है, लेकिन मैंने देखा कुछ और यह वास्तव में एक टिप्पणी में फिट नहीं होगा।
यदि आप किसी मौजूदा बनावट को प्रतिस्थापित करने के लिए पृष्ठभूमि में बनावट लोड करने के लिए GLKTextureLoader
का उपयोग कर रहे हैं, तो आपको मुख्य थ्रेड पर मौजूदा बनावट को हटाना होगा। पूरा होने वाले हैंडलर में एक बनावट को हटाने काम नहीं करेगा।
- हर आईओएस धागा अपनी ही EAGLContext आवश्यकता है, इसलिए पृष्ठभूमि कतार उसके अपने संदर्भ के साथ अपने स्वयं धागा है:
AFAIK इस वजह से है।
- पूरा होल्डर आपके द्वारा पारित कतार पर चलाया जाता है, जो संभवतः मुख्य कतार नहीं है। (वरना आप पृष्ठभूमि में लोड हो रहा है कर रही हैं नहीं किया जा ...)
है, इस स्मृति रिसाव हो जाएगा।
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft:@YES};
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self.asyncTextureLoader textureWithContentsOfFile:@"my_texture_path.png"
options:options
queue:queue
completionHandler:^(GLKTextureInfo *texture, NSError *e){
GLuint name = self.myTexture.name;
//
// This delete textures call has no effect!!!
//
glDeleteTextures(1, &name);
self.myTexture = texture;
}];
इस मुद्दे आप या तो चारों ओर पाने के लिए:
- बनावट हटाएं से पहले अपलोड होता है। आपके जीएल आर्किटेक्टेड के आधार पर संभावित रूप से स्केची।
- पूरा होने वाले हैंडलर में मुख्य कतार पर बनावट हटाएं।
तो, रिसाव को ठीक करने के आप ऐसा करने की जरूरत है:
//
// Method #1, delete before upload happens.
// Executed on the main thread so it works as expected.
// Potentially leaves some GL content untextured if you're still drawing it
// while the texture is being loaded in.
//
// Done on the main thread so it works as expected
GLuint name = self.myTexture.name;
glDeleteTextures(1, &name)
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft:@YES};
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self.asyncTextureLoader textureWithContentsOfFile:@"my_texture_path.png"
options:options
queue:queue
completionHandler:^(GLKTextureInfo *texture, NSError *e){
// no delete required, done previously.
self.myTexture = texture;
}];
या
//
// Method #2, delete in completion handler but do it on the main thread.
//
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft:@YES};
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self.asyncTextureLoader textureWithContentsOfFile:@"my_texture_path.png"
options:options
queue:queue
completionHandler:^(GLKTextureInfo *texture, NSError *e){
// you could potentially do non-gl related work here, still in the background
// ...
// Force the actual texture delete and re-assignment to happen on the main thread.
dispatch_sync(dispatch_get_main_queue(), ^{
GLuint name = self.myTexture.name;
glDeleteTextures(1, &name);
self.myTexture = texture;
});
}];
हम्म। अब तक कोई प्रतिक्रिया नहीं है, इसलिए यह इस समय आधिकारिक है क्योंकि यह इस समय मेरे लिए मिलता है। :-) मेरी सोच यह होगी कि 'जीएलकेटेक्चरइन्फो' इसका प्रबंधन करेगा (यानी बनावट को जारी करने के लिए इसे इंगित करने वाले हैंडल को संभालने में संभाल लें) लेकिन स्पष्ट रूप से यह मामला नहीं है। – alokoko
मुझे विश्वास है कि यह करने का यह सही तरीका है। मुद्दा यह है कि जब आप जीएल में बनावट को बांधते हैं तो आपके बनावट इंफो को बनाया जाता है, जीएल के बाद मेमोरी का मालिक होता है, इसलिए आपको स्मृति –
मेमोरी हटाने के लिए जीएल का उपयोग करने की आवश्यकता है, एंथॉयज स्पष्टीकरण मुझे समझ में आता है। +1। – Soup