2015-08-29 14 views
7

A mio modo di vedere l'immagine, i dati per la visualizzazione dell'immagine provengono da Url, le immagini sono circa 1-3 MB. Se l'utente salta, allora voglio caricare l'immagine successiva, Ogni cosa funziona bene se strisciata lentamente, ma quando ho fatto scorrere velocemente voglio annullare l'operazione precedente e iniziare con il nuovo URL.NsoperationQueue Annullare tutte le operazioni non è cancellato fino a quando non termina l'operazione

Per es. se l'utente fa scorrere 4 volte se le operazioni per la 2a e 3a immagine sono nel mezzo, voglio cancellarle e iniziare a scaricare la 4a immagine

Ma ora Al posto della 4a immagine sto ottenendo la prima 2a immagine segue 3a e poi appare la 4 ° immagine.

Ecco il mio codice di esempio

- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)aSwipeGestureRecognizer { 


    [BackgroundOperation cancelAllOperations]; // To cancel previous one 


    [self performSelector:@selector(LoadImage) withObject:nil afterDelay:0.1]; 


} 

-(void)LoadImage 
{ 
    BackgroundOperation=[[NSOperationQueue alloc]init]; 


    imgvww.image=[UIImage imageNamed:@"loader.png"]; // Place holder till download finishes 


    [BackgroundOperation addOperationWithBlock:^ 
    { 
     UIImage *img=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.ItemDetails objectAtIndex:0] objectForKey:@"ImageUrl"]]]]; // Getting data from URL 

     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 


      imgvww.image=img; //Adding to image view after completion 


     }]; 

    }]; 
} 

Grazie.

+0

Si prega di fare uno sforzo per formattare il codice in modo che altre persone possano leggerlo. – jtbandes

+1

Stai ricreando 'BackgroundOperation' ogni volta che un'immagine deve essere caricata (con' BackgroundOperation = [[NSOperationQueue alloc] init]; ')? –

risposta

5

Annullamento di un'operazione imposta semplicemente il flag isCancelled su true.

È responsabilità dell'utente controllare se l'operazione è stata annullata, prima che inizi a essere eseguita (o mentre è in esecuzione, se è un'operazione di lunga durata).

È possibile check if your operation is cancelled within an operation block ma io raccomanderei la sottoclasse, invece di usare un blocco.

+0

Non ho capito chiaramente, Sembra che v debba controllare isCancelled.Ma ho confuso dove controllare nel mio codice –

+0

Im non usando Nsoperation, Sembra isCancelled esistono per nsoperation –

+0

'NSBlockOperation' è una sottoclasse di' NSOperation'. Può essere cancellato. Controlla di nuovo il collegamento e guarda come cattura il blocco (debole) Operazione, quindi è possibile verificare il comando Cella nel blocco. Se non sei ancora sicuro su come farlo, [controlla questo articolo dettagliato] (http://nghiatran.me/advanced-issues-the-right-way-to-load-content-in-backgrounds-thread-with -tableview /) che annulla anche le operazioni di blocco. –

4

Chiamare cancelAllOperations su un NSOperationQueue chiamerà semplicemente cancel su ciascuna delle sue operazioni. Se lo NSOperation non sostituisce cancel, non verrà mai annullato.

Non esiste alcun concetto di cancellazione di NSBlockOperation dopo l'avvio. Il blocco esegue semplicemente e questo è quello.

Se si desidera specificare un comportamento di annullamento speciale (come la cancellazione del download dell'immagine) è necessario creare una sottoclasse di NSOperation e sovrascrivere cancel.

Ci sono molti esempi di questo in AFNetworking o SDWebImage

Per annullare una scarica immagine è necessario per avvolgere un NSURLSesionDownloadTask in un NSOperation e poi ignorare cancel chiamare cancel sul NSURLSesionDownloadTask

+0

non c'è bisogno di sottoclasse una NSOperation per poter annullare, è possibile farlo all'interno del blocco eseguito – Yariv

+1

Questo annullerà il blocco sì ma una volta avviato il download dell'immagine non è possibile fermarlo semplicemente usando dataWithContentsOfURL – DBoyer

+0

'cancel' è in realtà non ha chiamato tutte le operazioni, imposta semplicemente 'isCancelled' su YES – trapper

3

L'annullamento dell'operazione aggiornerà solo la sua proprietà isCancelled a YES.
Per essere in grado di annullare l'operazione, è necessario effettuare le seguenti operazioni:

NSBlockOperation * op = [NSBlockOperation new]; 
__weak NSBlockOperation * weakOp = op; // Use a weak reference to avoid a retain cycle 
[op addExecutionBlock:^{ 
    // Put this code between whenever you want to allow an operation to cancel 
    // For example: Inside a loop, before a large calculation, before saving/updating data or UI, etc. 
    if (weakOp.isCancelled) return; 

    // Do something.. 
];