ios - framework - xcode user guide




blocchi sincronizzati e dispatch_async (2)

Il lucchetto ci impedirebbe solo l'invio di due blocchi diversi contemporaneamente. Tuttavia vengono inviati in modo asincrono, quindi possono essere eseguiti in quel momento o possono essere eseguiti arbitrariamente in un lontano futuro. Anche la chiamata di spedizione non aspetterà che si completino.

Quindi le cose all'interno del blocco non sono sincronizzate. Le opzioni per raggiungere questo obiettivo con modifiche minime sono una distribuzione sincrona o solo @ sincronizzazione con il blocco.

A seconda di cosa stai facendo, l'idea migliore potrebbe essere quella di stabilire una coda di invio seriale e inviare i blocchi su quello.

Cosa succede al blocco in IOS usando @synchronized () quando chiamiamo dispatch_async () all'interno del blocco.

Per esempio:

    id myID
-(void) foobar
{
    @synchronized(myID){
        dispatch_async(){ //do stuff with myID};
    }
}

Il blocco è ancora valido all'interno della chiamata dispatch_async? O ancora più importante c'è qualche inconveniente nell'usare un'altra chiamata @synchronized () all'interno di dispatch_async ()?


Supponendo che tu stia cercando di sincronizzare l'interazione con questo oggetto myID nella coda di sfondo, lo vuoi viceversa, il blocco all'interno del blocco inviato. In questo momento hai:

@synchronized(myID) {
    dispatch_async(queue, ^{
         // do stuff with myID
    });
}

Questo sincronizza il processo di aggiunta del blocco inviato alla tua coda, ma non sincronizza ciò che stai facendo in background. Sospetto che non sia quello che intendevi.

Probabilmente hai inteso:

dispatch_async(queue, ^{
    @synchronized(myID) {
         // do stuff with myID
    }
});

Sembra molto simile, ma si traduce in un comportamento completamente diverso. Ora, il lavoro inviato alla coda in background è in fase di sincronizzazione.

Come ulteriore raffinamento, se questo blocco inviato è possibilmente lento (e presumo che possa essere), probabilmente vorrai limitare il più @synchronized blocco @synchronized :

dispatch_async(queue, ^{

    // do slow stuff in preparation for interacting with `myID`

    @synchronized(myID) {
         // quickly do stuff with myID
    }

    // do anything else here
});

Se si esegue tutto il blocco in background all'interno di un blocco @synchronized , è possibile @synchronized l'intero scopo di @synchronized allo sfondo, ovvero minimizzare l'impatto sulla coda principale. Quest'ultima interpretazione mitiga quel problema.

Come osservazione finale, se si dispone di una coda seriale (o di una coda concorrente non globale in cui si esegue l'aggiornamento con una barriera), questa viene spesso utilizzata come una tecnica che elimina del tutto la necessità di serrature, purché tutti gli aggiornamenti e le richieste per myID vengono inviati a quella coda. Vedere Eliminazione del codice basato su blocco nella Guida alla programmazione della concorrenza.





dispatch-async