> On Feb 25, 2016, at 13:31, Jens Alfke <j...@mooseyard.com 
> <mailto:j...@mooseyard.com>> 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 = [NSURL 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      (Xcode-users@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/xcode-users/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to