objective c - blocks - El bloque retiene implícitamente el ''yo''; Menciona explícitamente "yo" para indicar que se trata de un comportamiento intencionado.
blocks objective c (5)
Detalles
Xcode: 9.2
Advertencias en las cápsulas de Objective-C
Tengo proyecto veloz. El Block implicitly retains ''self''; explicitly mention ''self'' to indicate this is intended behavior
advertencia Block implicitly retains ''self''; explicitly mention ''self'' to indicate this is intended behavior
Block implicitly retains ''self''; explicitly mention ''self'' to indicate this is intended behavior
cuando uso los pods de Objective-C:
- Tornillos
- FBSDKCoreKit
- FBSDKLoginKit
Solución 1 (manual)
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = NO
Solución 2 (automática)
Agregue al final de su Podfile:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings[''CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF''] = ''NO''
end
end
end
Resultados
Dado lo siguiente:
- (void) someMethod
{
dispatch_async(dispatch_get_main_queue(), ^{
myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
target: self
selector: @selector(doSomething)
userInfo: nil
repeats: NO];
});
}
Donde myTimer se declara en una interfaz privada:
@interface MyClass()
{
NSTimer * myTimer;
}
@end
¿Cómo se arreglaría uno la siguiente advertencia?
Block implicitly retains ''self''; explicitly mention ''self'' to indicate this is intended behavior
De lo que he encontrado hasta ahora, la mayoría de las sugerencias involucran poner algo como:
- (void) someMethod
{
__typeof__(self) __weak wself = self;
dispatch_async(dispatch_get_main_queue(), ^{
wself.myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
target: self
selector: @selector(doSomething)
userInfo: nil
repeats: NO];
});
}
Excepto que myTimer es un ivar, lo que significa que wself
no tiene acceso a ninguna propiedad.
Supongo que mis preguntas son:
- ¿Debo / debería importarme?
- ¿Debo declarar myTimer como una propiedad?
Utilizo ivars bastante a través de mi código. Acabo de agregar el indicador " -Weverything
lo -Weverything
a mi proyecto para ver si puedo encontrar algún problema subyacente y esta es, con mucho, la advertencia más común. Sin embargo, no tengo ningún problema para solucionarlo al hacer mis propiedades ivars, pero quiero asegurarme de que tengo una mejor comprensión antes de hacerlo.
Esto soluciona mi problema para Xcode 9.3
- (void) someMethod{
__weak MyClass *wSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
MyClass *sSelf = wSelf;
if(sSelf != nil){
wself.myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
target: self
selector:@selector(doSomething)
userInfo: nil
repeats: NO];
}
});
}
Para aquellos de ustedes que reciben estas advertencias debido a Bolts
/ FBSDKCoreKit
/ FBSDKLoginKit
, deben evitar la respuesta de Vasily y, en su lugar, silenciar las advertencias para esas dependencias específicas.
Opción 1
Mencione cada pod en lugar de solo FacebookCore y agregue inhibit_warnings: true
pod ''FacebookCore'', inhibit_warnings: true
pod ''Bolts'', inhibit_warnings: true
pod ''FBSDKCoreKit'', inhibit_warnings: true
pod ''FBSDKLoginKit'', inhibit_warnings: true
opcion 2
O silenciar todas las vainas, agregando a tu Podfile esto:
inhibit_all_warnings!
Conclusión
Aún recibirás advertencias para tu propio código. No obtenerlos podría ser problemático en algún momento, por eso creo que es una solución mejor.
La próxima vez que actualice el SDK de Facebook, vea si puede eliminar inhibit_warnings: true
o inhibit_all_warnings!
.
Recientemente enfrenté el mismo problema y la respuesta de @Vasily Bodnarchuk parece ser útil.
Sin embargo, en entornos de integración continua no es posible cambiar el indicador CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
a NO
en el tiempo de ejecución. Así que para aislar el problema, probé comprobando todos los GEMS dependientes instalados por Cocoapods y descubrí que la versión 1.5.7 de XCODEPROJ de gema establece el CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF
en YES
siempre que se ejecute el comando pod install
. La solución para esto es revertir el XCODEPROJ a la versión anterior 1.5.1 ejecutando sudo gem install xcodeproj -v 1.5.1
Una vez revertido, simplemente ejecute pod install
y el indicador se establecerá en NO siempre.
Reemplazar myTimer
por self->myTimer
solucionaría su advertencia.
Cuando use una iVar _iVar
en el código, el compilador reemplazará el código por self->_iVar
, y si lo usa dentro de un bloque, el bloque se capturará a sí mismo en lugar de a la propia iVar. La advertencia es solo para asegurarse de que el desarrollador entienda este comportamiento.