name keywords google etiquetas ejemplos description objective-c xcode block nullable

objective c - keywords - Cómo usar palabras clave Objective-C no nulas y anulables en el método API basado en bloques



meta name keywords (6)

De acuerdo con el Blog de Apple ("Nulabilidad y Objetivo-C") , puede usar

NS_ASSUME_NONNULL_BEGIN y NS_ASSUME_NONNULL_END .

Dentro de estas regiones, se supondrá que cualquier tipo de puntero simple no es nonnull . Luego, puede agregar nullable para objeto nullable, que como

NS_ASSUME_NONNULL_BEGIN @interface MyClass: NSObject - (void)methodWithArg:(NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler; @end NS_ASSUME_NONNULL_END

  • si el error es del tipo NSError ** , debe ser NSError * _Nullable * _Nullable
  • si el objeto es id * type, mejor use id _Nullable * _Nonnull , depende (puede ser que desee un _Nullable id * _Nullable type).
  • si el objeto es del tipo NSObject * , necesita poner una anotación después del puntero, como este NSObject * _Nullable * _Nonnull

Nota

_Nonnull y _Nullable deben usarse después del puntero o id (Apple lo hace en el código de ejemplo AAPLListItem * _Nullable ), pero las formas no subrayadas nonnull y nonnull pueden usarse después de un paréntesis abierto.

Sin embargo, en el caso común, hay una forma mucho más agradable de escribir estas anotaciones: dentro de las declaraciones de métodos, puede usar los formularios no subrayados que se pueden nullable y no nonnull inmediatamente después de un paréntesis abierto, siempre que el tipo sea un objeto simple o un puntero de bloque.

ver más en "Nulabilidad y Objetivo-C"

Por seguridad, hay algunas excepciones a esta regla:

  • typedef tipos typedef no suelen tener una nulabilidad inherente; pueden ser fácilmente anulables o no anulables según el contexto. Por lo tanto, no se supone que los tipos typedef sean no nonnull , incluso dentro de las regiones auditadas.
  • Los tipos de puntero más complejos como id * deben anotar explícitamente. Por ejemplo, para especificar un puntero no anulable a una referencia de objeto anulable, use _Nullable id * _Nonnull .
  • El tipo particular NSError ** se usa con tanta frecuencia para devolver errores a través de parámetros del método que siempre se supone que es un puntero anulable a una referencia NSError anulable.

El _Nullable id * _Nonnull puede confundirse, id _Nullable * _Nonnull es una mejor comprensión.

_Nonnull y _Nullable deben usarse después del puntero o id (Apple lo hace en el código de ejemplo AAPLListItem * _Nullable )

Considere el siguiente método

- (void)methodWithArg:(NSString *)arg1 andArg:(NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

Con las nuevas palabras clave de anotación no nonnull y nullable podemos enriquecerla de la siguiente manera:

- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

pero también recibimos esta advertencia:

Al puntero le falta un especificador de tipo de anulabilidad (__nulo o nulo)

Se refiere al tercer parámetro (el bloque uno).

La documentación no cubre con ejemplos cómo especificar la nulabilidad de los parámetros de bloque. Dice textualmente

Puede usar las formas no subrayadas anulables y no nulas inmediatamente después de un paréntesis abierto, siempre que el tipo sea un objeto simple o un puntero de bloque.

Intenté poner una de las dos palabras clave para el bloque (en cualquier posición) sin suerte. También probé las variantes prefijadas de subrayado ( __nonnull y __nullable ).

Por lo tanto, mi pregunta es: ¿cómo puedo especificar la semántica de nulabilidad para los parámetros de bloque?


Del blog de desarrolladores de Apple: The Core: _Nullable y _Nonnull

puede usar las formas no subrayadas anulables y no nulas inmediatamente después de un paréntesis abierto , siempre que el tipo sea un objeto simple o un puntero de bloque.

Los formularios no subrayados son más bonitos que los subrayados, pero aún así necesitará aplicarlos a cada tipo en su encabezado .


Esto es lo que he usado para el caso NSError **:

-(BOOL) something:(int)number withError:(NSError *__autoreleasing __nullable * __nullable)error;


Esto parece estar funcionando

- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(nullable void (^) (NSArray * _Nullable results, NSError * _Nonnull error))completionHandler

Debe especificar la nulabilidad tanto para el bloque como para sus parámetros ...

EDITAR: para obtener más información, consulte Swift Blog


Para definir las terminaciones en un archivo de encabezado hice esto

typedef void (^PublicEventsHandler) (BOOL success, NSArray * _Nullable publicEvents);

Por supuesto, estoy de acuerdo con la respuesta aceptada.


También puedes hacer así:

- (id __nullable)methodWithArg:(NSString * __nullable)arg1 andArg:(NSString * __nonnull)arg2 completionHandler:(void (^ __nonnull)(NSArray * __nonnull results, NSError * __nullable error))completionHandler;

Solo depende de la sintaxis que más te guste.