Tuesday 19 December 2017

Consistent property attribute formatting in Objective-C

For those of us that care about consistent code formatting there are a few tools out there, including Objective-C support in uncrustify. However, one aspect of formatting  I have not found is to provide a consistent order for the property attributes. Often I'll see code such as the following:-

@interface ViewController()

@property (weak, nonatomic) IBOutlet UIButton *button1;
@property (weak, nonatomic) IBOutlet UIButton *button2;
@property (null_resettable, nonatomic) UIColor *highlightColor;
@property (nonatomic, copy) NSArray *names;
@property (getter=isActive, assign) BOOL active;

@end

This can be a bit of a jumble as there is no consistency in the ordering which causes a lot of cognitive work when reading as I need to read the full list of attributes on each line to see any patterns. To that end I've created a python script that will re-order these source files for me. In this example it would produce: -

@interface ViewController()

@property (nonatomic, weak) IBOutlet UIButton *button1;
@property (nonatomic, weak) IBOutlet UIButton *button2;
@property (nonatomic, null_resettable) UIColor *highlightColor;
@property (nonatomic, copy) NSArray *names;
@property (atomic, assign, getter=isActive) BOOL active;

@end

Now all the nonatomic attributes are move to the front as this is the most common attribute. You'll also notice that for the active property we added the atomic attribute that was not in the original source code. This is because atomic is the default unless nonatomic is specified, however atomic is rarely needed unless dealing with multiple threads, more often than not people simply forget to add nonatomic. By adding it, it makes the behaviour more explicit.

To run the script you simply supply a list of source files. It will work with both header and source files. The script will create a copy of the original source file prior to modifying it, this will have the same name as the original but with .orig suffixed on the name.

sort_prop_attrs.py <sourcefile1> <sourcefile2> <sourcefile3> ...

No comments:

Post a Comment