Statement
Conditional statements
The conditional statement body should always be surrounded by braces. It is best to add only one line of code, otherwise it will bring security risks.
// recommend
if (!error) {
return success;
}
// Not recommended
if (!error)
return success;
if (!error) return success;
Yoda Expression (Yoda)
Do not use Yoda expressions. (The name originated from Master Yoda's speech in Star Wars, always in reverse word order)
// recommend
if ([myValue isEqual:@42]) { ...
// Not recommended
if ([@42 isEqual:myValue]) { ...
nil and BOOL inspection
Some people like to check nil in this way:
if (nil == myValue) { ...
Doing this can avoid the error of one less "=", because once you write one less "=", then nil cannot be assigned and the compiler will report an error.
But mentioned earlier, it is best not to use Yoda expressions. So a better solution is to use "!" to complete the nil and BOOL check.
// recommend
if (someObject) { ...
if (![someObject boolValue]) { ...
if (!someObject) { ...
// Not recommended
if (someObject == YES) { ... // Wrong
if (myRawValue == YES) { ... // Never do this.
if ([someObject boolValue] == NO) { ...
Don't nest multiple if statements
Instead of nesting multiple if statements, use multiple returns to avoid increasing complexity and improve code readability.
That is to say, in a method, try not to place important parts in the if statement, but put "other situations" in the if.
// recommend
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
// Not recommended
- (void)someMethod {
if ([someOther boolValue]) {
//Do something important
}
}
Complex expressions
When a judgment condition is complex, they should be extracted and assigned to a BOOL variable.
BOOL nameContainsSwift = [sessionName containsString:@"Swift"];
BOOL isCurrentYear = [sessionDateCompontents year] == 2014;
BOOL isSwiftSession = nameContainsSwift && isCurrentYear;
if (isSwiftSession) {
// Do something very cool
}
Triple operator
The ternary operator must be readable.
// recommend
result = a > b ? x : y;
// Not recommended
result = a > b ? x = c > d ? c : d : y;
When the second parameter of the ternary operator (if branch) returns the same object as the object that has been checked in the conditional statement, the following expression is more clever:
// recommend
result = object ? : [self createObject];
// Not recommended
result = object ? object : [self createObject];
Error handling
Some methods return a reference to error through parameters. When using such methods, the return value of the method should be checked instead of the reference to error.
// recommend
NSError *error = nil;
if (![self trySomethingWithError:&error]) {
// Handle Error
}
If there is only one line of code, you don’t need to add braces, but multiple lines need to be added.
switch (condition) {
case 1:
// ...
break;
case 2: {
// ...
// Multi-line example using braces
break;
}
case 3:
// ...
break;
default:
// ...
break;
}
Enumeration type
Use the NS_ENUM() macro to define enums, which have more powerful type checking and code completion.
typedef NS_ENUM(NSUInteger, ZOCMachineState) {
ZOCMachineStateNone,
ZOCMachineStateIdle,
ZOCMachineStateRunning,
ZOCMachineStatePaused
};
variable
Try to use long, descriptive methods and variable names.
// recommend
UIButton *settingsButton;
// Not recommended
UIButton *setBut;
Constants should be named after camel method and prefixed with the relevant class name.
// recommend
static const NSTimeInterval ZOCSignInViewControllerFadeOutAnimationDuration = 0.4;
// Not recommended
static const NSTimeInterval fadeOutTime = 0.4;
Constants are recommended instead of string literals and numbers. It can be easily reused and quickly modified.
Constants should be declared as static constants with static, not #define unless it is explicitly used as a macro.
// recommend
static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";
static const CGFloat ZOCImageThumbnailHeight = 50.0f;
// Not recommended
#define CompanyName @"Apple Inc."
#define magicNumber 42
If a constant needs to be exposed to the outside, it should be in the header file in the form:
extern NSString *const ZOCCacheControllerDidClearCacheNotification;
and assign it a value in the implementation file.
Only public constants need to add namespace as prefix. Although the naming of private constants in implementation files can follow another pattern, you can still follow this rule.
A space should be added between the method name and the method type (-/+ symbol).
Method segments should also be spaced.
There should be a descriptive keyword before the parameters.
Use the word “and” as little as possible, it should not be used to clarify that there are multiple parameters.
// recommend
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
// Not recommended
- (void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height; // Never do this.
Use literals to create immutable NSString, NSDictionary, NSArray and NSNumber objects.
In this way, be careful not to put nil in NSArray and NSDictionary, as this will cause crashes.
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
Don't do this:
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018];
Avoid creating mutable arrays like this:
NSMutableArray *aMutableArray = [@[] mutableCopy];
This approach has problems in efficiency and readability.
Efficiency: An unnecessary immutable array is immediately discarded after being created, and it is not necessary.
Readability: Readability is not good.