With Xcode 6.3 there were new annotations introduced for better expressing the intention of API's in Objective-C (and to ensure better Swift support of course). Those annotations were of course nonnull
, nullable
and null_unspecified
.
But with Xcode 7, there is a lot of warnings appearing such as:
Pointer is missing a nullability type specifier (_Nonnull, _Nullable or _Null_unspecified).
In addition to that, Apple uses another type of nullability specifiers, marking their C code (source):
CFArrayRef __nonnull CFArrayCreate(
CFAllocatorRef __nullable allocator, const void * __nonnull * __nullable values, CFIndex numValues, const CFArrayCallBacks * __nullable callBacks);
So, to sum up, we now have these 3 different nullability annotations:
nonnull
,nullable
,null_unspecified
_Nonnull
,_Nullable
,_Null_unspecified
__nonnull
,__nullable
,__null_unspecified
Even though I know why and where to use which annotation, I'm getting slightly confused by which type of annotations should I use, where and why. This is what I could gather:
- For properties I should use
nonnull
,nullable
,null_unspecified
. - For method parameters I should use
nonnull
,nullable
,null_unspecified
. - For C methods I should use
__nonnull
,__nullable
,__null_unspecified
. - For other cases, such as double pointers I should use
_Nonnull
,_Nullable
,_Null_unspecified
.
But I'm still confused as to why we have so many annotations that basically do the same thing.
So my question is:
What is exact difference between those annotations, how to correctly place them and why?
Very handy is
and closing with
This will nullify the need for the code level 'nullibis' :-) as it sort of makes sense to assume that everything is non-null (or
nonnull
or_nonnull
or__nonnull
) unless otherwise noted.Unfortunately there are exceptions to this as well...
typedef
s are not assumed to be__nonnull
(note,nonnull
does not seem to work, have to use it's ugly half brother)id *
needs an explicit nullibi but wow the sin-tax (_Nullable id * _Nonnull
<- guess what that means...)NSError **
is always assumed nullableSo with the exceptions to the exceptions and the inconsistent keywords eliciting the same functionality, perhaps the approach is to use the ugly versions
__nonnull
/__nullable
/__null_unspecified
and swap when the complier complains... ? Maybe that is why they exist in the Apple headers?Interestingly enough, something put it into my code... I abhor underscores in code (old school Apple C++ style guy) so I am absolutely sure I did not type these but they appeared (one example of several):
And even more interestingly, where it inserted the __nullable is wrong... (eek@!)
I really wish I could just use the non-underscore version but apparently that does not fly with the compiler as this is flagged as an error: