ios - cast - Al puntero le falta un especificador de tipo de nulabilidad
el puntero cast (6)
En Xcode 7 GM comencé a recibir esta advertencia:
Al puntero le falta un especificador de tipo de nulabilidad (_Nnnull, _Nullable o _Null_unspecified)
En la siguiente declaración de función (extensión NSUserDefaults)
- (void)setObject:(nullable id)value
forKey:(NSString *)defaultName
objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler
objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;
¿Por qué se muestra esta advertencia y cómo debo solucionarla?
Para deshabilitar esta advertencia en todo su proyecto
-
Ir a la configuración de compilación
-
Asegúrese de que está viendo la pestaña "Todos", no "Básica" o "Personalizada"
-
Busque el campo
Other Warning Flags
-
Agregue el siguiente indicador:
-Wno-nullability-completeness
. -
Ahora limpia y construye (cmd + shift + k luego cmd + r)
-
Salga de xCode y vuelva a abrir ( ¡No omita este paso! )
--nota, las advertencias pueden tardar unos segundos en desaparecer incluso después de que termines de compilar y relanzar xCode, para mí toma aproximadamente 15 segundos para que xCode se actualice por completo
Elimine la macro a continuación de su archivo .h y la advertencia desaparecerá
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END
La declaración correcta del método de trabajo, aceptada por el compilador:
- (void)setObject:(nullable id)value
forKey:(nonnull NSString *)defaultName
objectChanged:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))changeHandler
objectRamains:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))remainHandler;
Puede usar las siguientes macros alrededor de bloques de declaraciones (funciones y variables) en encabezados de objetivo c:
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
Luego debe agregar anotaciones anulables para referencias que pueden ser nulas dentro de ese bloque. Esto se aplica tanto a los parámetros de la función como a las declaraciones de variables.
Como en:
@interface SMLBaseUserDetailsVC : UIViewController < UICollectionViewDelegate>
NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) IBOutlet UIScrollView *detailsScrollView;
@property (nonatomic, readonly) IBOutlet UICollectionView *photoCV;
@property (nonatomic, weak, readonly) SMLUser *user;
- (IBAction)flagUser:(id)sender;
- (IBAction)closeAction:(nullable id)sender;
- (void) prefetchPhotos;
NS_ASSUME_NONNULL_END
@end
Editar * ¿Por qué? es porque para que una clase objetiva-c sea interoperable con swift, debe declarar la nulabilidad para que el compilador sepa tratar las propiedades como opcionales swift o no. Las propiedades objetivas anulables c se conocen como opcionales en swift y el uso de estas macros junto con los declaradores anulables de propiedades permite al compilador tratarlas como opcionales (las opcionales son mónadas, un objeto que envuelve el objeto o nulo).
_Nonnull
esta respuesta para decir por qué debería agregar
_Nonnull
o
nullable
.
De acuerdo con este blog: https://developer.apple.com/swift/blog/?id=25
Una de las mejores cosas de Swift es que interopera de manera transparente con el código Objective-C, ambos marcos existentes escritos en Objective-C y el código en su aplicación. Sin embargo, en Swift hay una fuerte distinción entre referencias opcionales y no opcionales, por ejemplo,
NSView
vs.NSView?
, mientras que Objective-C representa ambos de estos dos tipos comoNSView *
. Debido a que el compilador Swift no puede estar seguro de si unNSView *
particular es opcional o no, el tipo se introduce en Swift como unNSView!
opcional sin envolver implícitamenteNSView!
.
Todo es para Swift.
nullable
especificar
nullable
también para los controladores / bloques
- (void)setObject:(nullable id)value
forKey:(nonnull NSString *)defaultName
objectChanged:(nullable void(^)(NSUserDefaults *userDefaults, id value))changeHandler
objectRamains:(nullable void(^)(NSUserDefaults *userDefaults, id value))remainHandler;
¿Por qué? Se debe a Swift. Swift permite parámetros opcionales (?), Que Objective-C no. Esto se hace como un puente entre ambos para que el compilador Swift sepa que esos parámetros son opcionales. Un ''No nulo'' le dirá al compilador Swift que el argumento es el requerido. Un nulo que es opcional
Para obtener más información, lea: https://developer.apple.com/swift/blog/?id=25