2013-10-08 10 views
5

sto usando ARC e l'applicazione si blocca dicendo avviso di memoria ricevuto. Sto testando l'applicazione direttamente sul dispositivo (iPhone 4 con iOS 7.0.2) e compilando con XCode 5 usando l'SDK di iOS 6. Ho usato gli strumenti Apple e ho a disposizione circa 20 MB di LiveByte allocati.Come eseguire il debug incidente iOS a causa della pressione della memoria

App at start

Dopo 4-5 minuti la mia applicazione ha 30 MB di memoria.

App status after 5 min

Dopo la compilazione e testare l'app sul dispositivo vedo che incidente dopo pochi minuti, subito dopo il messaggio di avviso di memoria. Perché non si verificano incidenti con gli strumenti? Tuttavia sto cercando di chiarire questo problema per un mese e non posso ottenere il rito della cosa, e ho davvero bisogno di aiuto. Sembra che non ci siano perdite ma non riesco a trovare dove è sbagliato. Grazie in anticipo per qualsiasi consiglio.

+0

Ho un'app che ha funzionato bene sul mio iPad 2 ... fino a quando non ho aggiornato a iOS 7, ora si è bloccato a causa della 'pressione della memoria'. Hai capito come risolvere questo? – j9suvak

+0

Ho essenzialmente lo stesso problema, potrei pubblicare presto un'altra domanda se non riesco a trovare la risposta altrove. – MattLoszak

+1

Ho risolto il mio problema, controllo la mia risposta. – andreapavan

risposta

3

ho risolto il problema. Nel mio caso, la pressione della memoria, era dovuta all'utilizzo costante della memoria da un ciclo del ciclo di esecuzione. Il ciclo viene eseguito ogni secondo e funziona su dati che devono essere analizzati e presentati nelle viste. Un'altra cosa, inizialmente il progetto non stava usando ARC. Dopo un progetto di conversione in ARC si è verificato il problema.

Prima della conversione del progetto di ARC, alla fine del ciclo ho avuto una chiamata diretta per la liberazione di risorse. Con ARC ovviamente questo viene fatto automaticamente, e il problema è proprio questo. Quindi, per la classe che esegue il ciclo, sono tornato alla versione non ARC e ho utilizzato i trucchi per eseguire manualmente il rilascio delle risorse utilizzate.

I blocchi del pool di autorelease forniscono un meccanismo in base al quale è possibile rinunciare alla proprietà di un oggetto, ma evitare la possibilità che venga deallocato immediatamente (ad esempio quando si restituisce un oggetto da un metodo). In genere, non è necessario creare blocchi del pool di autorelease, ma ci sono alcune situazioni in cui è necessario o è utile farlo.

@autoreleasepool { 
    // Code that creates autoreleased objects. 
} 

Alla fine del blocco piscina autorelease, oggetti che hanno ricevuto un messaggio autorelease all'interno del blocco viene inviato un messaggio-un rilascio oggetto riceve un messaggio di rilascio per ogni volta che è stato inviato un messaggio autorelease all'interno del blocco.

è possibile inserire un blocco @autoreleasepool intorno a qualsiasi sezione di codice, ma davvero non dovrebbe fare quello che penso che stai facendo.

Autorelease è molto meno efficiente che permettere di aggiungere ARC nel trattenere e rilasciare le chiamate per voi, ed è potenzialmente pericoloso. Autorelease mette tutti i tuoi oggetti in un "pool" e poi quando sei fuori dall'ambito e/o ogni volta che decide di scaricare il pool, "scarica" ​​il pool e i conteggi di conservazione degli oggetti vengono decrementati di uno.

La risposta breve: omettere completamente i blocchi @autorease, a meno che Apple non indichi diversamente nella documentazione o nel modello (ad esempio, main.m avrà un @autoreleasepool in esso).

Questo significa che gli oggetti potrebbero potenzialmente ottenere rilasciato prima si voleva davvero a loro. I blocchi @autoreleasepool sono più utili quando hai un ciclo molto stretto di codice che istanzia e poi scarta una quantità enorme di oggetti. Ad esempio, un ciclo for che elabora un enorme database e assegna oggetti stringa e quindi utilizza tali oggetti stringa per riempire le proprietà delle istanze di una classe che hai creato.In questo caso, ARC potrebbe non rilasciare tali oggetti in modo affidabile mentre si è all'interno del ciclo for e potrebbe essere necessario creare un pool di autorelease.

Tuttavia, ARC non sta facendo la cosa giusta in un circuito chiuso non è molto comune. È davvero più un concetto non ARC, in cui si utilizza un NSAutoreleasePool e lo si scarica manualmente.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

Spero di aver aiutato gli altri con lo stesso problema.

+1

Penso che tu sia giunto a una conclusione errata qui, '@ autoreleasepool's sono ancora utili in ARC e non solo in loop stretti. Ho visto l'aiuto di '@ autorelease' con problemi di pressione della memoria nella mia app quando ho a che fare con I/O di memoria di grandi dimensioni. Inoltre: http://stackoverflow.com/questions/9086913/objective-c-why-is-autorelease-autoreleasepool-still-needed-with-arc – Shizam

+1

@andreapavan. ho lo stesso problema Ho ottenuto 5k record dal servizio web di quello che sto inserendo tutto questo record in db. Ogni volta che viene registrato correttamente un record di 3k rispetto all'arresto dell'app. Il mio ciclo verrà eseguito 5 volte quando inserisco 5k record. quindi va bene implementare il metodo autoreleasepool in loop? – Hitarth

+0

Il mio era un caso piuttosto speciale perché dovevo mettere le mani su un progetto sviluppato in più passaggi. Come detto Shizam, anche autoreleasepool sono utili se usi ARC. In genere, non è necessario creare blocchi del pool di autorelease, ma ci sono alcune situazioni in cui è necessario o è utile farlo. Ho avuto un problema tra ARC e il blocco autoreleasepool. Nella vecchia implementazione questo è stato gestito manualmente, e l'ho mantenuto in questo modo. Ho indicato nelle impostazioni che la classe non utilizza ARC e ho gestito la memoria manualmente utilizzando un blocco autoreleasepool dove necessario. – andreapavan

0
#pragma mark - Received Memory Warning 

//memory pressure ios 
- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] && self.view.window == nil) 
    { 
     self.view = nil; 
    } 

    // Dispose of any resources that can be recreated. 
} 
Problemi correlati