Non è una risposta diretta, ma qualcosa che ho notato e non si adatta veramente a un commento.
Se si utilizza GLKTextureLoader
per caricare trame sullo sfondo per sostituire una trama esistente, è necessario eliminare la trama esistente sul thread principale. L'eliminazione di una trama nel gestore di completamento non funzionerà.
per quanto ne so questo è perché:
- filo Ogni iOS richiede una propria EAGLContext, così la coda di fondo ha il suo filo con il proprio contesto.
- Il gestore di completamento viene eseguito sulla coda passata, che molto probabilmente non è la coda principale. (Altrimenti non sarebbe fare il caricamento in background ...)
Cioè, questo perderà la memoria.
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;
}];
Per ovviare a questo problema è possibile:
- Eliminare la trama prima che il caricamento avviene. Potenzialmente abbozzato a seconda di come è progettato il tuo GL.
- Elimina la trama nella coda principale nel gestore di completamento.
Così, per riparare la perdita dovete fare questo:
//
// 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;
}];
o
//
// 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;
});
}];
Hmmm. Nessuna risposta fino ad ora, quindi questo è il più ufficiale che mi viene in mente al momento. :-) Il mio pensiero sarebbe che il 'GLKTextureInfo' gestisse questo (cioè maneggio rilasciando le trame a cui punta quando viene deallocato) ma a quanto pare non è così. – alokoko
Credo che questo sia il modo corretto per farlo. Il problema è che dopo aver creato textureInfo quando si lega la texture a GL, GL possiede quindi la memoria, quindi è necessario utilizzare GL per cancellare la memoria. La spiegazione di –
Anthoys ha senso per me. +1. – Soup