2015-11-28 10 views
9

Sto lavorando a un gioco di carte in Swift 2.1 usando Xcode 7 e la mia app funziona correttamente nel simulatore ma si blocca quando la provo sul mio dispositivo .Xcode 7/Swift 2.1 "Messaggio dal debugger: terminato a causa di un problema di memoria"

Utilizzando i punti di interruzione, ho individuato l'arresto anomalo in un metodo NSTimer.scheduledTimerWithTimeInterval che viene eseguito dopo che si è verificata un'animazione (e quindi attiva un'altra animazione).

Ho pensato che forse era la dimensione delle mie immagini, in quanto alcune erano piuttosto grandi (> 4 MB), quindi ho compresso tutte le immagini nell'animazione, e in totale ora occupano meno di 1 MB.

Ho anche eseguito gli strumenti Zombie and Leak e non ho trovato nulla, quindi sono un po 'perplesso. Ecco il codice dove si blocca.

func animateOnDeal() { 
    self.playerAnimatedCard.hidden = false 
    self.dealerAnimatedCard.hidden = true 
    cardOneToDeal() 
} 

func cardOneToDeal() { 
    UIView.animateWithDuration(0.5, animations: { 
     self.playerAnimatedCard.center.x -= self.view.bounds.width 
     }, completion: {finished in self.flipCardOne()}) 
} 

func flipCardOne() { 
    self.playerAnimatedCard.playFlipAnimation() 
    NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: "cardTwoToDeal", userInfo: nil, repeats: false) 
} 

Ed ecco il codice che esegue effettivamente l'animazione (in una sottoclasse UIImageView):

func playFlipAnimation() { 
    self.image = UIImage(named: "cardback2.png") 
    self.animationImages = nil 
    var imgArray = [UIImage]() 

    for var x = 1; x <= 12; x++ { 
     let img = UIImage(named: "img\(x).png") 
     imgArray.append(img!) 
    } 

    self.animationImages = imgArray 
    self.animationDuration = 0.3 
    self.animationRepeatCount = 1 
    self.startAnimating() 

Come nota a margine, il debugger afferma semplicemente: "Messaggio da debugger: terminato a causa di problema di memoria ".

Qualsiasi aiuto sarebbe molto apprezzato, per favore fatemi sapere se avete bisogno di ulteriori informazioni. Grazie!

EDIT:

Quindi, al fine di verificare il lavoro svolto ancora un po ', ho cambiato func playFlipAnimation per iterare ed aggiungere 5 immagini al posto degli originali 12. Questo sembra aver risolto l'incidente, ma io sono ancora incerti sul perché avere più immagini sta bloccando l'applicazione in primo luogo.

+5

In fase di chiusura a causa di un problema di memoria non è necessariamente un'indicazione di una perdita. Se non lo hai già fatto, ti consiglio di fare un po 'di profilazione usando lo strumento Allocations per vedere esattamente dove sta avvenendo la tua crescita di memoria. Assicurati di spuntare "Record referti di riferimento" e prendi nota del numero di oggetti persistenti durante l'esecuzione della tua app sul dispositivo. Esistono numerosi tutorial online sullo strumento Allocations ma fammi sapere se hai bisogno di ulteriori indicazioni qui. –

+0

@DerekLee, grazie per il consiglio! Così ho eseguito lo strumento Allocations e ricevuto numerosi flag dal titolo "Un messaggio Objective-C è stato inviato a un oggetto" IDEActivityReport "non valido all'indirizzo all'indirizzo: 0x7fc5dda8bbf0." Ho provato a cercare questo messaggio ma non ho trovato nulla di sostanziale. Qualche idea su cosa potrebbe causarlo? – rdespoiu

+0

@DerekLee Quindi, per testarlo ancora, ho cambiato func playFlipAnimation per iterare e aggiungere 5 immagini invece dell'originale 12. Questo sembra aver risolto il crash, ma non sono ancora sicuro del motivo per cui avere più immagini è arresto anomalo dell'applicazione in primo luogo. – rdespoiu

risposta

1

Un paio di punti:

  1. Come Derek Lee ha già sottolineato le immagini possono essere molto intensivo di memoria. Nella mia esperienza, il runtime manterrà anche le immagini memorizzate nella cache in background per un periodo dopo il loro utilizzo. Ciò potrebbe essere pertinente alla tua situazione poiché, guardando il tuo codice, stai caricando un nuovo set di dodici immagini ogni volta che viene chiamata l'animazione. Se stai ripetendo quell'animazione un sacco di volte, questo si sommerà rapidamente a molta memoria, specialmente con file di immagine da 1 MB. In questo caso, anche se a prima vista può sembrare inefficiente, potresti prendere in considerazione l'inizializzazione di una matrice di immagini quando la classe è inizializzata, che puoi riutilizzare.

  2. Una cosa che si può fare quando si esegue un'iterazione su un loop che si sa sarà intensivo di memoria è posizionarlo in un autorespiratore automatico. Vedi il riferimento dello sviluppatore a: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html So che tecnicamente ARC dovrebbe essere tutto ciò che serve nel mondo moderno di iOS, ma questo ha funzionato per me quando stavo sviluppando una procedura molto intensiva di dati in una delle mie app.

  3. È improbabile che venga attivato un avviso di memoria in esecuzione in Simulator poiché non viene preso in considerazione il fatto che l'hardware sottostante disponga di una capacità considerevolmente maggiore rispetto al dispositivo di destinazione. Nella mia infinita saggezza, una volta ho lasciato qualcosa in esecuzione che ha finito per usare 50GB di memoria ma che non ha attivato alcun tipo di avvertimento su Simulator!

  4. Per inciso, penso che dovresti essere in grado di comprimere le immagini della tua carta fino a molto meno di 1 MB. Ovviamente ciò dipenderà dal tipo di immagine che si desidera utilizzare (sono le foto?), Ma se si tratta di un semplice file .png, mi sembra abbastanza grande.

Spero che questo aiuti.

2

Ho incontrato lo stesso problema e ho scoperto che era il problema di controllare lo Abilita oggetti Zombie nello schema. Quindi puoi anche controllarlo. enter image description here

+0

Ho fatto lo stesso ... Ma ancora problema di fronte dopo aver memorizzato 15 immagini di Sqlite db. –

Problemi correlati