• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag
 

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How to fix "misuse of 'nonnull'" warnings in Xcode 7.3?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to fix "misuse of 'nonnull'" warnings in Xcode 7.3?


  • Subject: Re: How to fix "misuse of 'nonnull'" warnings in Xcode 7.3?
  • From: Devin Coughlin <email@hidden>
  • Date: Fri, 26 Feb 2016 15:41:40 -0800


On Feb 25, 2016, at 13:31, Jens Alfke <email@hidden> wrote:
As an experiment I tried turning on the new “misuse of ’nonnull'” warning in Xcode 7.3, and got a ton of warnings. They all make sense, but assuming I were going to correct my code, I don’t know the best way go about it. For example, here’s a real warning reported in my project:
[hostArray addObject: url.host]; // Warning!
Here the problem is that NSURL.host returns a nullable NSString, but -[NSArray addObject:]’s parameter is not nullable.

If I know that the URLs I’m dealing with all have hostnames in them, I could just add an “!” after `url.host`. Except I can’t because this is Obj-C, not Swift. What’s the equivalent? Do I have to add a cast?
[hostArray addObject: (NSString* _Nonnull)url.host];

If I don’t want to trust that the URL has a host, I can use `if let` to test it. But again, what’s the Obj-C equivalent? It seems like I’d need
NSString* _Nonnull host = url.host;
if (host)
[hostArray addObject: host];

The Xcode release notes say this warning is on by default in new projects, so people are going to start running into these issues, but I haven’t seen any explanation of how to resolve them. 

One thing to note is that there are two build settings in Xcode 7.3 related to nullability: 
- "Incorrect Uses of Nullable Values", a compiler warning, which is always *off* by default; and
- "Misuse of ’nonnull’", a static analyzer warning, which is the one enabled by default for newly created projects starting in Xcode 7.3 beta 3.

It looks like your warning above is from the compiler warning.

When "Incorrect Uses of Nullable Values" is enabled, Xcode passes the "-Wnullable-to-nonnull-conversion" flag to the compiler. This flag warns when an _expression_ of _Nullable type is used where a _Nonnull type is expected. With this build setting, the compiler will warn on your first example:

[hostArray addObject: url.host]; // Warning: implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'id _Nonnull'

This warning can be quite noisy, which is why it is disabled by default. The recommended mechanism for suppressing the warning is to store the value into a local of the the same type but with unspecified nullability:
 
NSString *host = url.host;
  [hostArray addObject:host];

This kind of suppression is useful when there is a high-level invariant that guarantees that the _Nullable value is not nil — for example when fetching an object from an NSDictionary that you know contains the key. As Sean McBride noted later in the thread, you can add an assert() if you want run-time checking of this invariant when assertions are enabled.

The "Misuse of ’nonnull’" build setting is for the static analyzer. The setting is disabled for existing projects but enabled by default for newly created projects. When enabled, the static analyzer (i.e., “Analyze" in the “Product" Menu) will warn when you use a value that is known to be nil in a place where a _Nonnull value is expected.  The static analyzer will not warn for "[hostArray addObject: url.host];" because the analyzer doesn’t *know* that url.host is nil (just that it is nullable). But it will warn in the following case:

NSString *s = nil;
NSURL *url ="" URLWithString:s]; // Static analyzer warns here nil is passed to +URLWithString, which takes a _Nonnull argument.

The static analyzer warning is off by default for existing projects because it can produce a large number of warnings for large codebases. However, it has a much better ratio of true positives to false positives than the compiler setting so it is turned on for newly created projects. With the static analyzer you can suppress the warning with an assertion that the value is not nil.

Devin Coughlin
Apple Program Analysis Team
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Prev by Date: Re: How to fix "misuse of 'nonnull'" warnings in Xcode 7.3?
  • Next by Date: Re: Aggregate targets in Xcode - is there any documentation on this anywhere?
  • Previous by thread: Re: How to fix "misuse of 'nonnull'" warnings in Xcode 7.3?
  • Next by thread: Swift binding of NSEnumerator subclasses
  • Index(es):
    • Date
    • Thread