Domanda

Se uso [UIImage imageWithCGImage:], passando un CGImageRef, rilascerò CGImageRelease o UIImage se ne occuperà da solo quando viene deallocato?

La documentazione non è del tutto chiara. Dice & Quot; Questo metodo non memorizza nella cache l'oggetto immagine. & Quot;

Inizialmente ho chiamato imageWithCGImage: sul CGImageRef dopo averlo passato a malloc_error_break, ma ciò ha causato un <=> avviso nel Simulatore che sosteneva che si stava verificando un doppio libero.

È stato utile?

Soluzione

Sono d'accordo con te: la documentazione è confusa al meglio per questa API. In base alle tue esperienze, quindi, concluderei che sei responsabile della vita di entrambi gli oggetti: UIImage e CGImageRef. Inoltre, devi assicurarti che la durata di <=> sia almeno pari a <=> (per ovvi motivi).

Altri suggerimenti

Secondo regola fondamentale della gestione della memoria di Cocoa , un oggetto proprietario dovrebbe rilasciare l'oggetto posseduto quando non ne ha più bisogno. Altri oggetti sono responsabili dell'acquisizione e del rilascio della proprietà per conto proprio. Se un UIImage ha bisogno di un oggetto per persistere ma non lo conserva o lo copia, è un bug nell'implementazione di <=> e dovrebbe essere segnalato come tale.

Ho lo stesso problema in XCode 3.2.1 su Snow Leopard. Ho praticamente lo stesso codice di Jason.

Ho esaminato il codice di esempio di iPhone che utilizza imageWithCGImage e rilasciano sempre CGImageRef utilizzando CGImageRelease dopo una chiamata a malloc_error_break.

Quindi, si tratta di un bug nel simulatore? Ricevo sempre l'avviso <=> sulla console quando utilizzo <=>.

La proprietà in UIImage circa CGImage non è chiara. Sembra che non copi dealloc ma non è garantito dalla documentazione. Quindi dobbiamo gestirlo da soli.

Ho usato una nuova sottoclasse di -[UIImage CGImage] per gestire questo problema. Conservando semplicemente il passaggio <=> e rilasciandolo quando <=>.

Ecco un esempio.

@interface  EonilImage : UIImage
{
    @private
    CGImageRef      sourceImage;
}
- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation;

@end



@implementation     EonilImage

- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
{
    self    =   [super initWithCGImage:imageRef scale:scale orientation:orientation];

    if (self) 
    {
        sourceImage =   imageRef;
        CGImageRetain(imageRef);
    }

    return  self;
}
- (void)dealloc
{
    CGImageRelease(sourceImage);
    [super dealloc];
}
@end

Poiché la proprietà <=> restituita da <=> non è garantita essere la stessa <=> passata al metodo init, la classe memorizza <=> separatamente.

Stai usando Xcode 3.1 su Snow Leopard? Sto riscontrando lo stesso problema:

CGContextRef ctx = ...;
CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
UIImage * newImage = [[UIImage imageWithCGImage:cgImage] retain];

CGImageRelease(cgImage); // this should be OK, but it now crashes in Simulator on SL

Suppongo che l'aggiornamento a Xcode 3.2 risolverà il problema.

Non sono sicuro se questo aiuta, ma ho avuto un problema simile. Ho letto le risposte e poi ho fatto quanto segue che sembra averlo corretto:

CGImageRef cgImage = [asset thumbnail];
    UIImage *thumbImage = [[UIImage imageWithCGImage:cgImage ]retain];
    UIImageView *thumbImageView = [[UIImageView alloc] initWithImage:thumbImage];
    CGImageRelease(cgImage);

Ho usato il rilascio automatico come suggerito ma non è stato sufficiente. Uno a cui avevo aggiunto l'immagine a UIImageView ho quindi rilasciato cgImage.
Non si è arrestato in modo anomalo e si è posizionato correttamente. Perché - non ne ho idea ma ha funzionato.

La parte delle miniature delle risorse proviene dalla libreria ALAsset, a proposito, potresti aver bisogno di qualcos'altro lì.

lt &; Gt &; Non è la mia opinione. Ho avuto lo stesso problema. Secondo la documentazione

UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];

imho mantiene tutti i riferimenti corretti. Se stai usando un CGDataProvider, dai un'occhiata CGDataProviderReleaseDataCallback e impostare un punto di interruzione nel callback. Puoi vedere che viene chiamato correttamente dopo che [rilascia] & Nbsp; la tua immagine e puoi liberare () il tuo buffer di dati immagine lì.

"This method does not cache the image object."

Quindi UIImage ne prende la proprietà e quindi non dovresti rilasciare CGImageRef.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top