6

I was working on adding some nullability annotation to part of a header file, and I wanted the block to assume non-null, but pretty much every method afterwards was giving warning saying that I needed to add nullability annotations.

Example code for this below:

NS_ASSUME_NONNULL_BEGIN
- (void)testMethodWithParameter:(NSString *)par otherParameter:(NSString *)otherPar;
NS_ASSUME_NONNULL_END

- (void)methodThatShouldntNeedAnnotationWithText:(NSString *)txt;
//Warning: Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)

Am I understanding these Macros incorrectly? I thought it would contain the part that was said to be audited within the BEGIN/END block, but everything outside would still be _Null_unspecified

Is this working as intended, or is there something I have to do to make this work the way I thought?

NickCE
  • 409
  • 3
  • 7
  • 5
    I don't know if it is intentional or not, but I observed that as well. As soon as you have *any* nullability annotation in the interface file, you have to define nullability *everywhere* in that file. – Martin R Sep 08 '16 at 19:05
  • At least from my impression of how this works, it seems like `NS_ASSUME_NONNULL_END` doesn't do anything within an interface. The Apple Swift blog's example code shows the `BEGIN` before the `@interface` and the `END` after `@end` (for the interface). Maybe it isn't meant to be used WITHIN a the interface for just part of it. – NickCE Sep 08 '16 at 19:18

1 Answers1

3

NS_ASSUME_NONNULL_BEGIN makes any parameter to be assumed as a non null variable, therefore:

NS_ASSUME_NONNULL_BEGIN
- (void)testMethodWithParameter:(NSString *)par otherParameter:(NSString *)otherPar;
NS_ASSUME_NONNULL_END

is converted to:

- (void)testMethodWithParameter:(nonnull NSString *)par otherParameter:(nonnull NSString *)otherPar;

So, the absence of NS_ASSUME_NONNULL_BEGIN doesn't mean that every parameter is assumed to be nullable nor unspecified, you still have to define it. So, for the other method you have to specify what you want, if you want the text could be nullable then add the keyword to the parameter like this:

- (void)methodThatShouldntNeedAnnotationWithText:(nullable NSString *)txt;
Fantini
  • 2,067
  • 21
  • 32
  • And, for `testMethodWithParameter` that is what I want, but why am I getting warnings about `methodThatShouldntNeedAnnotationWithText` after the `NS_ASSUME_NONNULL_END` macro? – NickCE Sep 08 '16 at 19:13
  • What I meant, you have to specify the `nullability` on your parameters, you can achieve this by using a `MACRO` or by specifying it on every parameter. – Fantini Sep 08 '16 at 19:23
  • 1
    The `MACRO` is only affecting the method signatures between the `..._BEGIN` and `..._END`, so that's what the compiler is telling you, `methodThatShouldnt...` is missing the `nullability specifiers` – Fantini Sep 08 '16 at 19:26
  • 1
    Ah, is there any way to tell the compiler to assume that the rest of the header is unaudited? – NickCE Sep 08 '16 at 20:05
  • I think that's not possible (not sure tho), if you check the `NSObjCRuntime.h` (by cmd+clicking on `NS_ASSUME_NONNULL_BEGIN`) you can see the definition of that macro alone, I can't see anything like that to let the methods unaudited – Fantini Sep 08 '16 at 20:14
  • Yeah, I looked in there, hoping for `NS_ASSUME_NULL_UNSPECIFIED_BEGIN`, but it was not there. I can audit it, but didn't want to do the whole thing quite yet. – NickCE Sep 08 '16 at 20:37