[Objective-c] 014_OBJECTIVE-C Code specification Guide (top)

Source: Internet
Author: User
Tags case statement coding standards constant definition
This article is referenced (http://www.csdn.net/article/2015-06-01/2824818-objective-c-style-guide/1)

Having good coding standards can keep our code elegant, easy to read, and easy to maintain. Let's start from the following points.

Code organization

Use #pragma mark-to classify methods in function grouping and protocol / delegate implementations, following the general structure:
#pragma mark-Lifecycle
-(instancetype) init ()
-(void) dealloc {}
-(void) viewDidLoad {}
-(void) viewWillAppear: (BOOL) animated {}
-(void) didReceiveMemoryWarning {}
#pragma mark-Custom Accessors
-(void) setCustomProperty: (id) value ()
-(id) customProperty ()
#pragma mark-IBActions
-(IBAction) submitData: (id) sender ()
#pragma mark-Public
-(void) publicMethod {}
#pragma mark-Private
-(void) privateMethod {}
#pragma mark-Protocol conformance
#pragma mark-UITextFieldDelegate
#pragma mark-UITableViewDataSource
#pragma mark-UITableViewDelegate
#pragma mark-NSCopying
-(id) copyWithZone: (NSZone *) zone ()
#pragma mark-NSObject
-(NSString *) description ()
2.space

Set the indentation using 4 spaces, making sure to come in Xcode preferences.
Method curly braces and other curly braces (if / else / switch / while, etc.) are always opened on the same statement but closed on a new line.
Should:

if (user.isHappy) {
    // Do something
} else {
    // Do something else
}
Should not:

if (user.isHappy)
{
  // Do something
}
else {
  // Do something else
}
There should be one and only one line between methods, which helps to be more visually clear and easier to organize. The white space in the method should separate the functions, but it is usually extracted as a new method.
Use auto-synthesis first. But if necessary, @synthesize and @dynamic should each declare a new line in the implementation
3. Notes

When comments are needed, they should be used to explain why this particular code does it. Any comments used must be kept up to date or deleted
4. Naming

Apple's naming rules are as consistent as possible, especially the memory management rules (NARC) related to these.
Long, descriptive method and variable naming is fine.
Should:

UIButton * settingsButton;
Should not:

UIButton * setBut;
Constants should use camel case naming convention, capitalizing all words and prefixing them with class names.
Should:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
Should not:

static NSTimeInterval const fadetime = 1.7;
Attributes are also humped, but the first letter of the first word is lowercase. Use auto-synthesis for attributes instead of manually writing @synthesize statements unless you have a good reason.
Should:

@property (strong, nonatomic) NSString * descriptiveVariableName;
Should not:

NSString * descriptiveVariableName;
5. Underline

When using properties, instance variables should be accessed and changed using self. This means that all properties will have different visual effects, because they are preceded by self.
But there is a special case: In the initialization method, instance variables (for example, _variableName) should be used directly to avoid the potential side effects of getters / setters.
Local variables should not contain underscores.
6. Method

In method signatures, there should be a space after the method type (-/ + sign). There should also be a space between the sections of the method (in Apple's style). A descriptive keyword should be included before the parameter to describe the parameter.
The use of the word "and" should be retained. It should not be used for multiple parameters to illustrate, like the following example of initWithWidth: height:
Should:

-(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;
Should not:

-(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.
7. Variable

Variables are named as descriptively as possible. Single character variable naming should be avoided as much as possible, except in a for () loop.
The asterisk indicates that the variable is a pointer. For example, NSString * text is neither NSString * text nor NSString * text, except for constants in special cases.
Private variables should replace the use of instance variables whenever possible. Although using instance variables is an effective way, it prefers to use attributes to maintain code consistency.
Direct access to instance variables by using the ‘back’ property (_variable, with an underscore in front of the variable name) should be avoided, except in the initialization methods (init, initWithCoder :, etc ...), the dealloc method and custom setters and getters. For more information on how to use the Accessor method directly in the initialization method and dealloc, check here.
 Should:

@interface RWTTutorial: NSObject
@property (strong, nonatomic) NSString * tutorialName;
@end
Should not:

@interface RWTTutorial: NSObject {
  NSString * tutorialName;
}
8. Property characteristics

All property attributes should be listed explicitly to help novices read the code. The order of attribute properties should be storage, atomicity, which is consistent with the automatically generated code when connecting UI elements in Interface Builder.
Should:

@property (weak, nonatomic) IBOutlet UIView * containerView;
@property (strong, nonatomic) NSString * tutorialName;
Should not:

@property (nonatomic, weak) IBOutlet UIView * containerView;
@property (nonatomic) NSString * tutorialName;
NSString should use the copy attribute instead of the strong attribute. (Why? Even if you declare a property of NSString, someone may pass in an instance of NSMutableString and modify it without your attention)
Should:

@property (copy, nonatomic) NSString * tutorialName;
Should not:

@property (strong, nonatomic) NSString * tutorialName;
9. dot notation syntax

Dot syntax is a convenient way to encapsulate access method calls. When you use dot syntax, properties are still accessed or modified by using getter or setter methods. To learn more, read here.
Dot syntax should always be used to access and modify attributes, as it makes the code more concise. The [] symbol is more used in other examples.
Should:

NSInteger arrayCount = [self.array count];
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication] .delegate;
Should not:

NSInteger arrayCount = self.array.count;
[view setBackgroundColor: [UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
10. Literal

The literal values of NSString, NSDictionary, NSArray, and NSNumber should be used when creating immutable instances of these classes. Please note that nil values cannot be passed to NSArray and NSDictionary literals, as this will cause a crash.
Should:

NSArray * names = @ [@ "Brian", @ "Matt", @ "Chris", @ "Alex", @ "Steve", @ "Paul"];
NSDictionary * productManagers = @ {@ "iPhone": @ "Kate", @ "iPad": @ "Kamal", @ "Mobile Web": @ "Bill"};
NSNumber * shouldUseLiterals = @YES;
NSNumber * buildingStreetNumber = @ 10018;
Should not:

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 * buildingStreetNumber = [NSNumber numberWithInteger: 10018];
11. Constant

Constants are easy to reuse and quickly modify values without having to find and replace. Constants should be declared using static instead of #define, unless macros are used explicitly. should:

static NSString * const RWTAboutViewControllerCompanyName = @ "RayWenderlich.com";
static CGFloat const RWTImageThumbnailHeight = 50.0;
Should not:

#define CompanyName @ "RayWenderlich.com"
#define thumbnailHeight 2
12. Enumeration

When using enum, the new fixed base type specification is recommended because it has stronger type checking and code completion. The SDK now has a macro NS_ENUM () to help and encourage you to use a fixed base type.
typedef NS_ENUM (NSInteger, RWTLeftMenuTopItemType) {
  RWTLeftMenuTopItemMain,
  RWTLeftMenuTopItemShows,
  RWTLeftMenuTopItemSchedule
};
Explicit assignment (show the old k-style constant definition):

typedef NS_ENUM (NSInteger, RWTGlobalConstants) {
  RWTPinSizeMin = 1,
  RWTPinSizeMax = 5,
  RWTPinCountMin = 100,
  RWTPinCountMax = 500,
};
13.case statement

Braces are not required in case statements unless the compiler mandates them. When a case statement contains multiple lines of code, braces should be added.
switch (condition) {
  case 1:
    // ...
    break;
  case 2: {
    // ...
    // Multi-line example using braces
    break;
  }
  case 3:
    // ...
    break;
  default:
    // ...
    break;
}
Many times, a fall-through should be used when the same code is used in multiple cases. A fall-through is to remove the 'break' statement at the end of the case, which allows the execution flow to jump to the next case value. To make the code clearer, a fall-through needs to be commented.
switch (condition) {
  case 1:
    // ** fall-through! **
  case 2:
    // code executed for values 1 and 2
    break;
  default:
    // ...
    break;
}
When using an enum type in a switch, 'default' is not needed. E.g:
RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;
switch (menuType) {
  case RWTLeftMenuTopItemMain:
    // ...
    break;
  case RWTLeftMenuTopItemShows:
    // ...
    break;
  case RWTLeftMenuTopItemSchedule:
    // ...
    break;
}
14. Private Properties

Private attributes should be declared in the class extension (anonymous classification) in the class's implementation file. Named classifications (such as RWTPrivate or private) should never be used unless they extend other classes. Anonymous classification should be exposed to tests by using the naming convention of <headerfile> + Private.h file.
@interface RWTDetailViewController ()
@property (strong, nonatomic) GADBannerView * googleAdView;
@property (strong, nonatomic) ADBannerView * iAdView;
@property (strong, nonatomic) UIWebView * adXWebView;
@end
15. Boolean

Objective-C uses YES and NO. Because true and false should only be used in CoreFoundation, C or C ++ code. Since nil resolves to NO, there is no need to compare in conditional statements. Don't compare something directly with YES, because YES is defined as 1 and a BOOL can be set to 8 bits.

This is considered to be consistent across documents and more visually concise.

Should:

if (someObject) ()
if (! [anotherObject boolValue]) {}
Should not:

if (someObject == nil) ()
if ([anotherObject boolValue] == NO) {}
if (isAwesome == YES) {} // Never do this.
if (isAwesome == true) {} // Never do this.
If the name of the BOOL attribute is an adjective, the attribute can ignore the "is" prefix, but specify the customary name of the get accessor. E.g:
@property (assign, getter = isEditable) BOOL editable;
Text and examples quote the Cocoa Naming Guidelines from here.

17. Conditional statements

The body of a conditional statement should be surrounded by braces to prevent errors, even if the body of the conditional statement can be written without curly braces (for example, using only one line of code). These errors include adding a second line of code and expecting it to be an if statement; moreover, even more dangerous defect may occur in an if statement where one line of code is commented and then the next line of code unknowingly becomes part of the if statement. In addition, this style is consistent with the style of other conditional statements, so it is easier to read.
Should:

if (! error) {
  return success;
}
Should not:

if (! error)
  return success;
Or:

if (! error) return success;
18. Ternary operator

The ternary operator?: Is used when you need to improve the clarity and conciseness of your code. It is often needed for single condition evaluation. When evaluating multiple conditions, the code is more readable if you use if statements or reconstitute instance variables. In general, it is best to use the ternary operator when you are assigning values based on conditions.
Non-boolean variables are compared to something, and parentheses () improve readability. If the variable being compared is of type boolean, then no parentheses are required.
Should:

NSInteger value = 5;
result = (value! = 0)? x: y;
BOOL isHorizontal = YES;
result = isHorizontal? x: y;
Should not:

result = a> b? x = c> d? c: d: y;
19.Init method

The Init method should follow the naming rules of Apple generated code templates, and the return type should use instancetype instead of id.
-(instancetype) init {
  self = [super init];
  if (self) {
    // ...
  }
  return self;
}
20. Construction method

When a class constructor is used, it should return an instancetype instead of an id. This ensures that the compiler correctly infers the result type.
@interface Airplane
+ (instancetype) airplaneWithType: (RWTAirplaneType) type;
@end
For more instancetype information, please check NSHipster.com.

21.CGRect function

When accessing x, y, width, or height in CGRect, you should use the CGGeometry function instead of directly through the structure.
Should:

CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX (frame);
CGFloat y = CGRectGetMinY (frame);
CGFloat width = CGRectGetWidth (frame);
CGFloat height = CGRectGetHeight (frame);
CGRect frame = CGRectMake (0.0, 0.0, width, height);
Should not:

CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
CGRect frame = (CGRect) {.origin = CGPointZero, .size = frame.size};
22. Golden Path

When using conditional coding, the code on the left should be the "golden" or "happy" path. That is, do not nest if statements, and multiple return statements are also OK.
Should:

-(void) someMethod {
  if (! [someOther boolValue]) {
    return;
  }
  // Do something important
}
Should not:

-(void) someMethod {
  if ([someOther boolValue]) {
    // Do something important
  }
}
23. Error handling

When a method returns an error parameter by reference, determine the return value instead of the error variable.
Should:

NSError * error;
if (! [self trySomethingWithError: & error]) {
  // Handle Error
}
Should not:

NSError * error;
[self trySomethingWithError: & error];
if (error) {
  // Handle Error
}
成功 In the case of success, some Apple APIs record garbage values to error parameters (if non-NULL), then judging the error values will lead to false negative values and crash.

24. Singleton Mode

Singleton objects should use thread-safe mode to create shared instances.
+ (instancetype) sharedInstance {
  static id sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once (& onceToken, ^ {
    sharedInstance = [[self alloc] init];
  });
  return sharedInstance;
}
This will prevent possible and sometimes prolific crashes.

25.xcode project

Physical files should be synchronized with Xcode project files to avoid file expansion. The creation of any Xcode group should be reflected in the file of the file system. The code is not only grouped by type, but also by function, which makes the code more clear.
If possible, open "Treat Warnings as Errors" in the target's Build Settings and enable the following additional warnings. If you need to ignore special warnings, use Clang ’s pragma feature.
26. Other specifications

If our coding standards do not meet your taste, you can check other coding standards:

Robots & Pencils
New York Times
Google
GitHub
Adium
Sam Soffes
CocoaDevCentral
Luke Redpath
Marcus Zarra


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.