Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Tune Your Header File Part 2: Nullability

DZone's Guide to

Tune Your Header File Part 2: Nullability

If you're looking to migrate your Objective-C code to Swift, it's important to get nullability right in your header. Know the keywords and how they'll impact your code.

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

In the first post, I put the focus on the initializers. In this post, I would like to put nullability into the spotlight. I would also explain why is it a good practice and how it will help you migrate your existing Objective-C code into Swift.

Nullable/Nonnull

The idea behind using the nullable/nonnull keyword is to protect our code against the accidental nil values, which might crash our app in runtime. As I mentioned in the Embrace Compile Time Errors post, it is better that the developer has early warning about the problem, so it won’t escalate to the runtime error.

With the Nullable and Nonnull keywords we, as developers, can clearly and explicitly define that the class property or the method variables and return value can be nil or not. Examples:


@property (weak, nonatomic, nullable) id progressDelegate;

For an object type property, it is quite easy to use. Just add the nullable/nonnull for the property attributes.


@property (unsafe_unretained, nonatomic) BOOL isAllModelParsed;

For the primitive types, there is no sense or need to add nullability.


- (nullable instancetype)init;

As you can see even the initializer return value (instancetype) can have the nullability attribute.


- (nullable instancetype)initWithModelControllers:(nullable NSArray *) models NS_DESIGNATED_INITIALIZER;

It works together with generics and is applicable for the method parameters, not just the return values.


- (void)startPopulateDrawNumbersWithCompletionHandler:(void (^_Nonnull)(BOOL
wasSuccessfull, NSArray * _Nullable numbers))callback;

And it can be applied on the blocks as well. Please note the use of underscore (_Nonnull/_Nullable). Essentially, this is same. The only difference is that without the underscore, you can use it before the type definition, but after the type definition, (like NSArray) you can use only the underscored version. Unfortunately, blocks are quite picky about this. You can find a good set of different definitions here.

What to Consider and Decide About Nullability

Although you can either ignore this advice, or try to cheat a little bit with NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END macros, if you want to implement nullability in your header file, then be prepared to challenge all of your non-primitive types properties and the method parameters with the return type as well.

If you set up even one variable with the nullability, clang will warn you to with the “Pointer is missing nullability type specifier” message. That means that ALL of your pointers in the header file need to have a clearly defined nullability.

Benefits

When the nullability properly set up and defined for all of our classes, it helps us in the early detection of errors or malfunction in cases when nil passed or set up for the variable.

If you're thinking about migrating your existing code to Swift, which needs to be done soon or later, you're already one step closer to figuring out which variables need to be Optional and which don't.

Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:
mobile ,swift ,ios ,tutorial ,null ,objective-c

Published at DZone with permission of Peter Molnar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}