77

In Xcode 7 GM I started to get this warning:

Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)

In the following function declaration (NSUserDefaults extension)

- (void)setObject:(nullable id)value
           forKey:(NSString *)defaultName
    objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;

Screenshot

Why this warning is showing and how should I fix it?

1
  • If you wish to actually disable the warning all together instead of just conforming your coding style to it, then see here: stackoverflow.com/a/57122456/2057171 Commented Jan 21, 2021 at 7:43

7 Answers 7

77

You can use the following macros around blocks of declarations (functions and variables) in objective c headers:

NS_ASSUME_NONNULL_BEGIN 

NS_ASSUME_NONNULL_END

You need to then add nullable annotations for references that can be nil within that block. This applies to both function parameters and variable declarations.

As in:

@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

Edit* why do we have to do this? For an objective-c class to be interoperable with swift, you need to declare nullability so that the compiler knows to treat properties as swift optionals or not. Nullable objective c properties are known as optionals in swift and using these macros in conjunction with the nullable declarators for properties allows the compiler to treat them as optionals (Optionals are objects that wrap up either the object or nil).

Sign up to request clarification or add additional context in comments.

2 Comments

Again, I think you should have explained why you have to use the macros around the blocs of declaration???
Plus 1. I had one .h file that was missing the annotations, and I got the error only on my first @property. This pointed me in the right direction.
64

You need to specify nullable also for the handlers/blocks

- (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;

Why? It's due to Swift. Swift allows optional parameters (?), which Objective-C does not. This is done as a bridge between the both of them for the Swift compiler to know those parameters are optional. A 'Nonnull' will tell the Swift compiler that the argument is the required. A nullable that it is optional

For more info read: https://developer.apple.com/swift/blog/?id=25

6 Comments

I must add that compiler is also points to specify something for the block parameters.
Are you asking why you need to specify them at all? Because of the interoperability with the Swift compiler. It determines whether the API is exposed as an optional or not. See the Apple Blog post here: developer.apple.com/swift/blog/?id=25
I second mskw reaction as well. Like why all of a sudden this is needed. Plus I am coding in ObjC so this has nothing to do with Swift crap.
@bandejapaisa Re: why… I'd say it's because Apple wants you to make you explicitly opt in to Tony Hoare's "billion dollar mistake." linkedin.com/pulse/…
@David天宇Wong I edited the answer to satisfy your "why".
|
21

To disable this warning across your entire project

  1. Go to Build Settings

  2. Make sure you are viewing the "All" tab not "Basic" or "Customized"

  3. Search for the field Other Warning Flags.

  4. Add the following flag: -Wno-nullability-completeness.

  5. Now clean and build (⇧⌘K then ⌘R)

  6. Quit Xcode and re-open it (Don't skip this step!)

Note: It can take a few seconds for the warnings to go away even after you finish building and relaunching Xcode, for me it takes about 15 seconds for Xcode to fully update.

  1. (2022 Edit), Double check that the warning flag setting persisted, for some reason the latest xCode often seems to not save this setting when I set it.

5 Comments

for Xcode 11 it seems to be -Wno-nonnull instead of -Wno-nullability-completeness
@budidino For me it's still -Wno-nullability-completeness confirmed on xCode 11.4.1
This works on Xcode 11.5, just don’t skip the step 6.
Disabling this warning won't cause any issue? ¯_(ツ)_/¯
@JayprakashDubey Correct, it's just a warning. If your code is good there will be no issue. But if you have something that needs to behave non-null and you pass null to it you yourself could encounter issues but that would be the case whether or not you had this warning disabled. This warning is to just help you prevent that, but if you know what you're doing then you can disable it, as it's a non-issue.
14

The correct, working method declaration, accepted by compiler:

- (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;

Comments

11

I post this answer to tell why should add _Nonnull or nullable.

According to this blog: https://developer.apple.com/swift/blog/?id=25

One of the great things about Swift is that it transparently interoperates with Objective-C code, both existing frameworks written in Objective-C and code in your app. However, in Swift there’s a strong distinction between optional and non-optional references, e.g. NSView vs. NSView?, while Objective-C represents boths of these two types as NSView *. Because the Swift compiler can’t be sure whether a particular NSView * is optional or not, the type is brought into Swift as an implicitly unwrapped optional, NSView!.

it's all for Swift.

Comments

3

Remove below macro from your .h file and warning will disappear

NS_ASSUME_NONNULL_BEGIN 

NS_ASSUME_NONNULL_END

2 Comments

Right. The simplest way to get around this warnings is to never anywhere in your code specify nullablility.
@osxdirk But adding these two lines does specify nullability. It marks everything as non-null.
0

Use:

#pragma clang diagnostic ignored "-Wnullability-completeness"

to disable the warning in a file.

3 Comments

FYI - It's better to fix the warning than to ignore it.
@HangarRash This is a warning, not an error, for a reason. If you're writing obj C, specially if you don't interface with Swift, this warning is irrelevant and bothering. However, I don't find this discussion interesting...
I never said it was an error. It's better to fix the actual cause of warnings. In this case it also makes your Objective-C code better. You don't need to be using Swift to get better Objective-C code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.