¿Cómo puedo evitar esta advertencia en xcode? Aquí está el fragmento de código:
[player(AVPlayer object) addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(0.1, 100)
queue:nil usingBlock:^(CMTime time) {
current+=1;
if(current==60)
{
min+=(current/60);
current = 0;
}
[timerDisp(UILabel) setText:[NSString stringWithFormat:@"%02d:%02d",min,current]];///warning occurs in this line
}];
objective-c
cocoa-touch
automatic-ref-counting
avplayer
retain
usuario1845209
fuente
fuente
timerDisp
una propiedad en la clase?player(AVPlayer object)
ytimerDisp(UILabel)
?Respuestas:
La captura de
self
aquí viene con su acceso implícito a la propiedad deself.timerDisp
: no puede hacer referencia a lasself
propiedadesself
desde dentro de un bloque que será fuertemente retenido porself
.Puede evitar esto creando una referencia débil
self
antes de accedertimerDisp
dentro de su bloque:fuente
__unsafe_unretained
lugar.self
retenido por la cola de despacho principal. ¿Me equivoco?Y una cosa muy importante para recordar: no use variables de instancia directamente en bloque, úselo como propiedades de un objeto débil, muestra:
y no te olvides de hacer:
puede aparecer otro problema si pasa una copia débil o no retenida por ningún objeto:
si
vcToGo
se desasignará y luego se disparará este bloque, creo que se bloqueará con un selector no reconocido en una papelera quevcToGo_
ahora contiene una variable. Intenta controlarlo.fuente
Mejor versión
Así que todo sería así:
He leído este artículo muchas veces. Este es un excelente artículo de Erica Sadun sobre cómo evitar problemas al usar bloques y NSNotificationCenter
Actualización rápida:
Por ejemplo, en swift, un método simple con bloque de éxito sería:
Cuando llamamos a este método y necesitamos usarlo
self
en el bloque de éxito. Usaremos las funciones[weak self]
yguard let
.Este llamado baile fuerte-débil es utilizado por un popular proyecto de código abierto
Alamofire
.Para obtener más información, consulte la guía de estilo rápida
fuente
typeof(self) strongSelf = self;
fuera del bloque (en lugar de __weak) luego en el bloque que se dicestrongSelf = nil;
después del uso? No veo cómo su ejemplo asegura que weakSelf no sea nulo para cuando se ejecute el bloque.En otra respuesta, Tim dijo:
Esto no es del todo cierto. Está bien que hagas esto siempre que rompas el ciclo en algún momento. Por ejemplo, supongamos que tiene un temporizador que se dispara que tiene un bloqueo que se retiene a sí mismo y también mantiene una fuerte referencia al temporizador en sí mismo. Esto está perfectamente bien si siempre sabes que destruirás el temporizador en algún momento y romperás el ciclo.
En mi caso, justo ahora, recibí esta advertencia para el código que hizo:
Ahora sé que clang solo producirá esta advertencia si detecta que el método comienza con "set" (y otro caso especial que no mencionaré aquí). Para mí, sé que no hay peligro de que haya un bucle de retención, así que cambié el nombre del método a "useY:" Por supuesto, eso podría no ser apropiado en todos los casos y generalmente querrá usar una referencia débil, pero Pensé que valía la pena señalar mi solución en caso de que ayude a otros.
fuente
Muchas veces, esto no es realmente un ciclo de retención .
Si sabes que no es así, no necesitas traer débiles infructuosos al mundo.
Apple incluso nos impone estas advertencias con la API
UIPageViewController
, que incluye un método establecido (que activa estas advertencias, como se mencionó en otra parte, pensando que está estableciendo un valor en un ivar que es un bloque) y un bloque de controlador de finalización (en el que sin duda te referirás a ti mismo).Aquí hay algunas directivas del compilador para eliminar la advertencia de esa línea de código:
fuente
Agregar dos centavos para mejorar la precisión y el estilo. En la mayoría de los casos, solo usará uno o un par de miembros
self
en este bloque, lo más probable es que solo actualice un control deslizante. El castingself
es exagerado. En cambio, es mejor ser explícito y lanzar solo los objetos que realmente necesita dentro del bloque. Por ejemplo, si se trata de una instancia deUISlider*
, digamos_timeSlider
, simplemente haga lo siguiente antes de la declaración de bloque:Luego, solo use
slider
dentro del bloque. Técnicamente, esto es más preciso, ya que reduce el ciclo de retención potencial solo al objeto que necesita, no a todos los objetos que contieneself
.Ejemplo completo:
Además, lo más probable es que el objeto que se está lanzando a un puntero débil ya sea un puntero débil en el interior, lo
self
que minimiza o elimina por completo la probabilidad de un ciclo de retención. En el ejemplo anterior, en_timeSlider
realidad es una propiedad almacenada como una referencia débil, por ejemplo:En términos de estilo de codificación, como en C y C ++, las declaraciones de variables se leen mejor de derecha a izquierda. Declarando
SomeType* __weak variable
en este orden lee de forma más natural de derecha a izquierda como:variable is a weak pointer to SomeType
.fuente
Me encontré con esta advertencia recientemente y quería entenderla un poco mejor. Después de un poco de prueba y error, descubrí que se origina por tener un método que comienza con "agregar" o "guardar". El objetivo C trata los nombres de métodos que comienzan con "new", "alloc", etc. como devolviendo un objeto retenido pero no menciona (que puedo encontrar) nada sobre "agregar" o "guardar". Sin embargo, si uso un nombre de método de esta manera:
Veré la advertencia en la línea [hecho a sí mismo]. Sin embargo, esto no:
Seguiré adelante y usaré la forma "__weak __typeof (self) weakSelf = self" para hacer referencia a mi objeto, pero realmente no me gusta tener que hacerlo, ya que confundirá a un futuro yo y / u otro desarrollador. Por supuesto, tampoco podría usar "agregar" (o "guardar"), pero eso es peor ya que elimina el significado del método.
fuente