Incluso la respuesta es correcta, no es una solución elegante y diferente:
- (id)init {
self = [super init];
if (self != nil) {
NSString *label = [NSString stringWithFormat:@"%@.isolation.%p", [self class], self];
self.isolationQueue = dispatch_queue_create([label UTF8String], NULL);
label = [NSString stringWithFormat:@"%@.work.%p", [self class], self];
self.workQueue = dispatch_queue_create([label UTF8String], NULL);
}
return self;
}
//Setter, write into NSMutableDictionary
- (void)setCount:(NSUInteger)count forKey:(NSString *)key {
key = [key copy];
dispatch_async(self.isolationQueue, ^(){
if (count == 0) {
[self.counts removeObjectForKey:key];
} else {
self.counts[key] = @(count);
}
});
}
//Getter, read from NSMutableDictionary
- (NSUInteger)countForKey:(NSString *)key {
__block NSUInteger count;
dispatch_sync(self.isolationQueue, ^(){
NSNumber *n = self.counts[key];
count = [n unsignedIntegerValue];
});
return count;
}
La copia es importante cuando se utilizan los objetos peligrosos de rosca, con esto se podría evitar el posible error debido a la liberación involuntaria de la variable . No es necesario contar con entidades seguras para hilos.
Si hay más cola le gustaría usar el NSMutableDictionary declarar una cola privada y cambiar el colocador a:
self.isolationQueue = dispatch_queue_create([label UTF8String], DISPATCH_QUEUE_CONCURRENT);
- (void)setCount:(NSUInteger)count forKey:(NSString *)key {
key = [key copy];
dispatch_barrier_async(self.isolationQueue, ^(){
if (count == 0) {
[self.counts removeObjectForKey:key];
} else {
self.counts[key] = @(count);
}
});
}
IMPORTANTE!
usted tiene que establecer una propia cola privada sin ella el dispatch_barrier_sync es sólo un simple dispatch_sync
explicación detallada se encuentra en este marvelous blog article.
No soy un experto en multihilo, pero sí sé que el indicador "atómico" (el predeterminado para @ accessors sintetizados) no garantiza la seguridad del hilo. Sin embargo, pensé lo mismo cuando leí por primera vez al respecto. –