Supongamos que tengo una simple llamada dispatch_async(self.queue, ^{ /* Empty */ })
, dónde self.queue
es una cola creada previamente.
Hace self
ser retenidos por el Bloque en este caso, dado que no hay self
referencia dentro el bloque, pero solo como un parámetro para dispatch_async()
?
Respuestas
0 para la respuesta № 1No, self
no se retendrá si el bloque no tiene ni (a) ninguna referencia explícita a self
; ni (b) ninguna referencia implícita a self
que se generan haciendo referencia a cualquier variable de instancia de self
. La presencia de self.queue
en la invocación de dispatch_async
no hará que se retenga. Es lo que importa dentro del bloque.
Esto es bastante fácil de demostrar. Imagine un controlador de vista cuya implementación se parece a:
@interface SecondViewController ()
@property (nonatomic, strong) dispatch_queue_t queue;
@end
@implementation SecondViewController
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.queue = dispatch_queue_create("com.stackoverflow.17306228", 0);
void (^block)(void) = ^(void){
sleep(10);
NSLog(@"%s", __FUNCTION__);
};
dispatch_async(self.queue, block);
}
@end
Si empuja a la escena de este controlador de vista yluego presione inmediatamente el botón "Atrás" para sacarlo, verá que el controlador de vista se desasignará inmediatamente y el bloque continuará ejecutándose. Pero si agrega una variable de instancia de clase o propiedad a la block
, verá el controlador de vista retenido hasta después de que se complete el bloque.
2 para la respuesta № 2
Ok, entonces los documentos de Apple establecen que
La cola es retenida por el sistema hasta que el bloque se haya ejecutado terminación.
Por lo tanto, el sistema retendrá la cola hasta que el bloque complete la ejecución, pero el self
no se retendrá en este caso.
Gracias a @Wain por señalar mi error en la versión anterior de esta respuesta.