5

incontrando numerose perdite sul dispositivo iphone utilizzando NSOperationQueue e cercando di cambiare cursori/raccoglitori eccincontrano numerose dispersioni sulla dispositivo iphone quando si utilizza NSOperationQueue e cercando di cambiare cursori/raccoglitori ecc

sono in grado di cambiare le etichette senza problema, ma se provo a cambiare un cursore o un selettore entrambi creati sul generatore di interfacce ottengo queste perdite.

codice
Leaked Object # Address Size Responsible Library   Responsible Frame 
GeneralBlock-16  0x1b00a0 16 GraphicsServices GetFontNames 
GeneralBlock-16  0x1aea90 16 WebCore    WebThreadCurrentContext 
GeneralBlock-16  0x1aea80 16 GraphicsServices GSFontGetFamilyName 
GeneralBlock-64  0x1a7370 64 UIKit     GetContextStack 

sotto

- (void)loadData { 

    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self 
                      selector:@selector(firstRun) 
                       object:nil]; 

    [queue_ addOperation:operation]; 
    [operation release]; 
} 

- (void)firstRun { 

    NSAutoreleasePool *pool = [NSAutoreleasePool new]; 

    [self setSliders]; 

    NSLog(@"firstRun method end"); 

    [pool drain]; 

} 

- (void)setSliders { 

    NSMutableArray *tempArray = [[[NSMutableArray alloc]init] autorelease]; 
    aquaplannerAppDelegate *appDelegate = (aquaplannerAppDelegate *)[[UIApplication sharedApplication] delegate]; 
    tempArray = appDelegate.settingsValuesArray; 

    freshMarineSegment.selectedSegmentIndex = [[tempArray objectAtIndex:0]intValue]; 

    for (int i = 1; i <= 20; i++) { 
     UILabel *label = (UILabel *)[self.view viewWithTag:200+i]; // gets label based on tag 
     UISlider *slider = (UISlider *)[self.view viewWithTag:100+i]; // gets slider based on tag 

     slider.value = [[tempArray objectAtIndex:i]intValue]; 
     label.text = [[[NSString alloc] initWithFormat:@"%@",[tempArray objectAtIndex:i]] autorelease]; 

     [label release]; 
     [slider release]; 
    } 
} 

risposta

7

Sto assumendo che stai facendo qualcos'altro prima setSliders per il quale è stato creato il NSOperation, e basta omesso quel codice.

UIKit non è garantito per essere thread-safe, e si dovrebbe solo accedere agli elementi dell'interfaccia sul thread principale. Questo è menzionato in alcuni punti della documentazione, ma la più significativa è nella Guida ai concetti fondamentali di Cocoa:

Tutti gli oggetti UIKit devono essere utilizzati solo sulla filettatura principale.

Così firstRun dovrebbe apparire più simile a questo:

- (void)firstRun { 

    NSAutoreleasePool *pool = [NSAutoreleasePool new]; 

    // Do something important here... 

    [self performSelectorOnMainThread:@selector(setSliders) withObject:nil waitUntilDone:NO]; 

    NSLog(@"firstRun method end"); 

    [pool drain]; 

} 

Perché stai usando un NSMutableArray in setSliders? In realtà non stai mai cambiando l'array, e le strutture di dati mutabili possono devastare la programmazione in thread.

Inoltre, rinominerei il metodo setSliders in qualcosa come updateSliders. È un problema in stile Cocoa. I metodi che iniziano con "set" devono essere utilizzati per la modifica di una singola variabile/proprietà di istanza.

+0

grazie per le tue informazioni, vedrò i miei metodi che potrebbero essere impostati. e sì performSelectorOnMainThread era la chiave, cercherò anche di cambiare i miei array in thread separati agli NSArrays se i loro oggetti non cambiano – zambono

0

si stanno rilasciando ogni etichetta e il cursore nel vostro ciclo for, anche se non li avete mantenuto. Questo non è corretto. È sufficiente liberare memoria che è stata allocata, copiata o conservata. Vedi la gestione della memoria programming guide per maggiori dettagli.

Vorrei anche cambiare il modo di inizializzare il tuo array temporaneo. L'inizializzatore designato per NSMutableArray è -initWithCapacity:, non -init. V'è anche un metodo di classe progettato per restituire un'istanza autoreleased per comodità:

NSMutableArray *tempArray = [NSMutableArray arrayWithCapcity:0]; 
+0

così ho apportato le modifiche al metodo, l'ho eseguito sul thread principale per verificare le perdite, nessuno, l'ho eseguito in NSOperatioQueue e ottengo le stesse perdite di prima. il problema deve fare qualcosa con la chiamata di questi oggetti creati dal generatore di interfacce da un thread che non è il principale – zambono

+0

Felice di aver capito che hai funzionato. Mantenere le modifiche che ho raccomandato, però. Queste parti sono importanti e imparare le corrette regole di gestione della memoria ti farà risparmiare un sacco di problemi lungo la strada. –

Problemi correlati