2011-10-17 3 views
7

Ho un progetto che scarica le immagini in background utilizzando NSOperationQueue. Fino ad ora funzionava su dispositivi con IOS 4.3. Tuttavia, se costruisco l'app con base sdk 4.3 o con 5 ed eseguo l'app sul dispositivo con IOS5, l'app si arresta in modo anomalo. Quando l'app viene avviata, aggiunge gli oggetti NSOperation in coda per il download delle immagini. Se tra premo il tasto indietro, a cancellare il NSOperation e si blocca e visualizza seguente traccia su console:NSOperationQueue non funziona in IOS5

 
#0 0x004727b7 in ____NSOQSchedule_block_invoke_0() 
#1 0x026a5618 in _dispatch_call_block_and_release() 
#2 0x026a7a10 in _dispatch_worker_thread2() 
#3 0x974bb781 in _pthread_wqthread() 
#4 0x974bb5c6 in start_wqthread() 

e stampe "ResourceLoadOperation isfinished = YES senza essere avviato dalla coda è in" Se io commento la chiamata al metodo cancel, l'app non si blocca. Esistono aggiornamenti sulle modifiche NSOperation per IOS5?

+0

Ho lo stesso problema. Commentare il rilascio dell'oggetto NSOperation fa il trucco, come hai detto tu, ma non sono molto sicuro che la gestione della memoria sia corretta in questo caso ... –

+0

Sì, solo commentare il metodo cancel potrebbe non essere corretto in termini di gestione della memoria. Ma questo è un problema della velocità di elaborazione in iOS 5 che causa questo problema poiché lo stesso funziona bene su dispositivi IOS 4.3? – CKT

risposta

12

Ho avuto questo stesso problema quando si costruisce contro iOS 5. Ho finito per la creazione di una bandiera di nome operationStarted che era NO di default e ho spostato verso YES quando il metodo start è stato chiamato. Quindi nel mio metodo finish (dove ho generato le notifiche KVO), ho controllato il valore della flag prima di attivare le notifiche.

La definizione bandiera assomiglia a questo:

@property (nonatomic, assign, getter=isOperationStarted) BOOL operationStarted; 

Il start metodo:

- (void)start { 
    [self setOperationStarted:YES]; 
    ... 
} 

Il mio metodo finish che viene chiamato quando l'operazione è stata completata o annullata:

- (void)finish {  
    if (![self isOperationStarted]) return; 

    [self willChangeValueForKey:@"isExecuting"]; 
    executing = NO; 
    [self didChangeValueForKey:@"isExecuting"]; 

    [self willChangeValueForKey:@"isFinished"]; 
    finished = YES; 
    [self didChangeValueForKey:@"isFinished"]; 
} 

Questo ha finito per risolvere il problema per me. Spero che aiuti qualcun altro.

+0

Sono curioso di sapere perché hai bisogno di proprietà operationStarted quando hai già eseguito la scansione per lo stesso scopo? –