Apple after Xcode 6.3, in order to solve the problem of Swift and OC mixed, introduced a new feature of objective-c: nullability annotations.
at the heart of this new feature are two different types of annotations: __nullable and __nonnull. We can literally guess that __nullable indicates that an object can be null or nil, while __nonnull means that the object should not be empty. When we do not follow this rule, the compiler gives a warning (compiler warning: Null passed to a callee that requires a non-null argument).
Reasons for introducing new features of nullability annotations:
In Swift, you can use! And? To indicate whether an object is optional or non-optional, such as view! and view, and in objective-c there is no such distinction, view can indicate that the object is optional, can also be expressed as non-optioanl.
This creates a problem: When Swift and objective-c are mixed, the Swift compiler does not know whether a Objective-c object is optional or non-optional, so in this case the compiler implicitly Objective The-C object is considered a non-optional.
Let's take a look at the following examples:
1 @interfaceStudentClass ()2 3@property (nonatomic, copy) Nsarray *Studentarray;4 5- (ID) Studentwithname: (NSString *__nonnull) name;6 7 @end8 9 @implementationStudentClassTen One- (void) testnullability { A [self studentwithname:nil]; - //Compiler Warning: Null passed to a callee that requires a non-null argument - } the -- (ID) Studentwithname: (NSString *__nonnull) name { - returnNil; - } + - @end
But this is just a warning that the program can be compiled and run.
In fact, you can use __nullable and __nonnull in any place where you can use the Const keyword, but these two keywords are limited to using pointer types.
In the declaration of the method, we can also use nullable and nonnull, which are not underlined, as follows:
-(Nullable ID) Studentwithname: (NSString *nonnull) name;
In the attribute declaration, there are two additional attributes added, so the Studentarray attribute in the example above can be declared as follows:
@property (nonatomic, copy, nonnull) Nsarray *studentarray;
Of course, you can do this in the following way:
@property (nonatomic, copy) Nsarray *__nonnull Studentarray;
It is recommended to use nonnull this way, so that the property declaration will look clearer.
However, for security reasons, Apple has also set several rules:
The nullability attribute of a type defined by a typedef is typically dependent on the context, and even in audited regions, it cannot be specified as nonnull.
A complex pointer type (such as ID *) must be shown to specify whether it is nonnull or nullable. For example, specify a nonnull pointer to the nullable object, and you can use __nullable ID *__nonnull.
The nserror that we often use is usually assumed to be a nullable pointer to the nullable Nserror object.
Because Nullability Annotations is a new addition to Xcode 6.3, we need to consider the old code before. In fact, Apple has helped us deal with this compatibility problem and we can safely use them:
The old code will still work, even if you use nil for the Nonnull object.
The old code will give a warning under the new Swift compiler when it needs to be mixed with Swift.
Nonnull does not affect performance, in fact, we can still judge whether our object is nil at runtime.
In fact, we can see the nonnull/nullable with our breakpoints and exceptions, and the problems that need to be dealt with are the same: the breach is a programmer's fault, and in particular, the return value is something we can control, and if the return value is nonnull, we should not return nil. Unless it is for backwards compatibility.
__nonnull and __nullable (Swift and Objective-c)