È raro che NSLock
sia lo strumento giusto per il lavoro. Ci sono strumenti molto migliori ora, in particolare con GCD; più tardi.
Come probabilmente già sapete da the docs, ma lo ripeto per chi legge insieme:
Attenzione: La classe NSLock utilizza i thread POSIX per attuare il suo comportamento di chiusura. Quando si invia un messaggio di sblocco a un oggetto NSLock, è necessario assicurarsi che il messaggio venga inviato dallo stesso thread che ha inviato il messaggio di blocco iniziale. Sbloccare un lucchetto da una filettatura diversa può comportare un comportamento indefinito.
Questo è molto difficile da implementare senza deadlock se si sta cercando di bloccare e sbloccare su thread diversi. Il problema fondamentale è che se lock
blocca il thread, non è possibile che il successivo unlock
venga eseguito su quel thread e che non sia possibile eseguire unlock
su un thread diverso. NSLock
non è per questo problema.
Anziché NSLock
, è possibile implementare gli stessi motivi con dispatch_semaphore_create()
. Questi possono essere tranquillamente aggiornati su qualsiasi thread che ti piace. Puoi bloccare utilizzando dispatch_semaphore_wait()
e puoi sbloccarlo utilizzando dispatch_semaphore_signal()
. Detto questo, questo è ancora il di solito non è la risposta giusta.
La maggior parte del conflitto di risorse viene gestita al meglio con una coda di operazioni o una coda di invio. Questi forniscono eccellenti modi per gestire il lavoro in parallelo, gestire le risorse, attendere gli eventi, implementare modelli produttore/consumatore, e in caso contrario fare quasi tutto ciò che avresti fatto con uno NSLock
o NSThread
in passato. Consiglio vivamente lo Concurrency Programming Guide come introduzione a come progettare con le code anziché i blocchi.
fonte
2013-04-11 15:24:37