2014-12-12 14 views
5

Ho creato un'app ed è (beh, era) pronta per essere inviata.Memory Warning & Crash ImageIO-jpeg-data

L'app è fondamentalmente una app per flash card per bambini dove ci sono 12 carte per pagina.

Attualmente è solo iPad e quando le carte vengono toccate una vista immagine si anima dalla scheda a schermo intero con una risoluzione massima di 2048 x 1536 e suona un suono dell'animale, si tocca l'immagine a dimensione intera e torna nella scheda. Ad ogni scheda sono assegnate 5 immagini. L'app ha funzionato perfettamente nonostante il periodo di progettazione e ora ho caricato tutti gli animali e l'ho testato e notato che si è bloccato.

Per farla breve la memoria aumenta di 12 MB per immagine (anche se ogni immagine è di circa 200-400 KB) fino a raggiungere 700 MB di memoria e si blocca. Questa memoria non si riduce mai.

Ho eseguito l'app tramite gli strumenti xcode e non vedo perdite, ma ho identificato in "Allocations" che è la categoria "ImageIO-jpeg-data" che è il colpevole.

Ho passato tutta la serata a leggere su questo perché ho trovato risultati promettenti, tuttavia questi risultati non hanno funzionato per me quindi presumo di aver frainteso ciò che è stato consigliato o non l'ho capito, quindi speravo che qualcuno potrebbe forse aiutarmi o spiegare in termini laici come posso risolvere questo.

OK per spiegare come è impostato il controller di visualizzazione.

Inizialmente ho impostato le 5 immagini per ogni scheda in un array ma c'era un ritardo, quindi qualcuno qui suggeriva di caricare le immagini in viewDidLoad e poi chiamarle quando si toccava la scheda/il pulsante.

Così, per esempio stavo usando questo formato in viewDidLoad

domestic100 = [UIImage imageNamed:@"ferret-00"]; 
domestic101 = [UIImage imageNamed:@"ferret-01"]; 
domestic102 = [UIImage imageNamed:@"ferret-02"]; 
domestic103 = [UIImage imageNamed:@"ferret-03"]; 
domestic104 = [UIImage imageNamed:@"ferret-04"]; 

e poi nel pulsante premuto ho assegnato l'immagine alla visualizzazione dell'immagine chiamando:

domestic01ImageContainer.image = domestic100; 

all'interno di un if else guarda se il numero dell'immagine è 1 a 4.

In ogni caso ha funzionato perfettamente (a parte questo problema memeory)

Ho letto online che mi sarebbe stato meglio dichiarare le UIImages utilizzando

[UIImage imageWithContentsOfFile:path] 

come si è visto in questo post: UIImage memory not deallocating VM: ImageIO_JPEG_DATA?

Così le modifiche che ho fatto nel mio codice sono:

nel mio viewDidLoad ora creo uiimages in questo modo:

domestic200 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-00" ofType: @"jpg"]]; 
domestic201 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-01" ofType: @"jpg"]]; 
domestic202 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-02" ofType: @"jpg"]]; 
domestic203 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-03" ofType: @"jpg"]]; 
domestic204 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-04" ofType: @"jpg"]]; 

e quindi nel pulsante pressato chiamare l'immagine al ImageView utilizzando

[domestic01ImageContainer setImage:domestic100]; 

sto ottenendo gli stessi risultati - l'immagine sono solo costruendo nella stessa memoria e non rilasciare o deallocando.

Non sono un mago quando si parla di obiettivo-c e questa è la mia prima vera app.

Se qualcuno potesse essere così gentile da riservare un momento del loro tempo per aiutarmi, sarei davvero riconoscente.

Grazie in anticipo.

****** Modifica ******

Così vi ho detto come mi carico le mie immagini sopra, ho anche nel viewDidLoad do i 12 imageviews un punto di partenza e una nascosta alfa.

domestic01ImageContainer = [[UIImageView alloc] initWithFrame:CGRectMake(30, 123, 152, 224)]; 
domestic01ImageContainer.Alpha = 0; 

Ho quindi aggiungere la visualizzazione secondaria con:

[self.view addSubview:domestic01ImageContainer]; 

ogni imageview viene assegnato un gesto rubinetto per nascondere l'immagine in un momento successivo:

UITapGestureRecognizer *domestic01Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTaped:)]; 
[domestic01ImageContainer addGestureRecognizer:domestic01Tap]; 
[domestic01ImageContainer setUserInteractionEnabled:YES]; 

Quando il pollice/carta è premuto una versione semplificata del pulsante sarebbe:

- (IBAction)domestic01ButtonClicked:(id)sender { 
static int imageNumber = 0; 

if (imageNumber == 0) { 
    [domestic01ImageContainer setImage:domestic100]; 
    imageNumber++; 
} 

else if (imageNumber == 1) { 
    [domestic01ImageContainer setImage:domestic101]; 
    imageNumber++; 
} 

else if (imageNumber == 2) { 
    [domestic01ImageContainer setImage:domestic102]; 
    imageNumber++; 
} 

else if (imageNumber == 3) { 
    [domestic01ImageContainer setImage:domestic103]; 
    imageNumber++; 

} 

else if (imageNumber == 4) { 
    [domestic01ImageContainer setImage:domestic104]; 
    imageNumber = 0; 
} 

domestic01ImageContainer.Alpha = 1; 

[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 
     domestic01ImageContainer.frame = CGRectMake(0, 0, 768, 1024); 
    } completion:^(BOOL finished) { 

}]; 

}

Il mio imageTapped riconoscitore per ridurre l'immagine full size Ritorno alla scheda che uso:

[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 
     domestic01ImageContainer.frame = CGRectMake(30, 123, 152, 224); 
    } completion:^(BOOL finished) { 
     domestic01ImageContainer.Alpha = 0; 
    }]; 

Che sostanzialmente messo la scheda flash di ritorno da schermo intero per le dimensioni della carta/miniature e il set alfa di nuovo a 0.

Come ho detto tutto funziona, ma come hai suggerito l'immagine viene mantenuta da qualche parte.

Spero che questo getti un po 'più di luce su ciò che potrebbe causare il problema.

Avevo provato a impostare l'immagine su zero dopo che l'alfa era impostato su 0 nell'immagineTappato, ma ciò non risolveva la memoria.

+0

Sembra che le tue immagini vengano conservate in un luogo che non ti aspetti. Stai assegnando le immagini a più di una variabile o proprietà? –

+0

Ciao Anna, aggiungerò una modifica alla mia domanda in modo da avere maggiori informazioni. Grazie –

+0

Quante immagini hai caricato in un dato momento? Non riesco a capire dalla tua descrizione. Se hai 12 x 5 immagini caricate contemporaneamente, sono 750 MB. Tieni presente che le immagini sono * non compresse * quando le assegni a un'immagineView e le immagini sono pari a 12,5 MB ciascuna. È necessario posticipare il caricamento delle immagini finché non sono necessarie. –

risposta

1

Stavo riscontrando un problema simile. La memoria veniva trattenuta in modo anomalo. Avevo un UImageView IBOutlet e stavo impostando la sua proprietà image con la proprietà UIImage del mio controller di visualizzazione, che avrei impostato durante l'inizializzazione del mio controller di visualizzazione. UIImageView manterrebbe erroneamente la proprietà UIImage del mio controller di visualizzazione anche quando tornerei al controller di visualizzazione radice.

Ho risolto il problema modificando proprietà UIImage del controller vista NSData e impostando la proprietà l'immagine del UIImageView come segue:

[_previewImageView setImage:[UIImage imageWithData:_previewImageData]]; 

Questo ha risolto il problema di ImageIO-JPEG-dati di essere di aiuto inutilmente. Spero che questo aiuti qualcuno.