raywenderlich.com OBJECTIVE-C Coding Specification

Source: Internet
Author: User
Tags case statement constant definition naming convention





  • Original link: The official raywenderlich.com objective-c style guide
  • Original Author: raywenderlich.com Team
  • Version: raywenderlich.com objective-c Coding Specification
  • Translator: Sam Lau


As I'm preparing to mimic the hungry app, there may be some iOS developers involved in it. At this point, if everyone's objective-c coding style is not the same, it is not easy to maintain code consistency and difficult codes Review. So I searched the internet for the official Raywenderlich.com Objective-c style guide article on objective-c coding style, and felt that it could be used as the OBJECTIVE-C coding standard for this project, So just translate this article.


raywenderlich.com OBJECTIVE-C Coding Specification


This coding style guide outlines the coding specifications for raywenderlich.com, which may be truncated or modified.


Introduced


The reason we developed the OBJECTIVE-C coding specification is that we are able to keep the code in our books, tutorials and starter kits elegant and consistent. Even though we have many different authors to complete different books.



The coding specification here may be different from the other OBJECTIVE-C encoding specifications you see, because it is primarily for printing and web legibility.


About the author


This coding specification was created by a lot of raywenderlich.com team members under the leadership of Nicholas Waynik. Team members are: Soheil moayedi azarpour, Ricardo Rendon cepeda,tony Dahbura, Colin Eberhardt, Matt Galloway, Greg Heo, Matthijs Holl Emans,christopher Lapollo, Saul Mora, Andy Pereira, Mic Pringle, Pietro Rea, Cesare Rocchi, Marin Todorov, Nicholas Waynik and Ray Wenderlich.



We are also very grateful to the authors of the new York times and Robots & Pencils ' objective-c coding specifications. These two coding specifications provide a good starting point for the creation of this guide.


Background


Here are some official Apple documents about coding style, if something is not mentioned, you can find more details in the following documents:


    • The OBJECTIVE-C programming Language
    • Cocoa Fundamentals Guide
    • Coding Guidelines for Cocoa
    • IOS APP Programming Guide
Directory
    • Language
    • Code Organization
    • Space
    • Comments
    • Named
      • Underline
    • Method
    • Variable
    • Attribute Properties
    • Dot symbol syntax
    • Literal value
    • Constant
    • Enum type
    • Case statement
    • Private properties
    • Boolean value
    • Conditional statements
      • Ternary operator
    • Init method
    • Class construction methods
    • CGRect function
    • Golden Path
    • Error handling
    • Single-Case mode
    • Line break
    • Xcode Project




Language


You should use US English.



Should:


UIColor *myColor = [UIColor whiteColor];


No:


UIColor *myColour = [UIColor whiteColor];




Code Organization


The classification method is used in the function grouping and protocol/delegate implementations to#pragma mark -follow the following 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 {}




Space
    • Indent uses 4 spaces to make sure that you set it in Xcode preferences. (raywenderlich.com use 2 spaces)
    • Method braces and other curly braces (if//else/switchwhileetc.) Always open in the same line statement but close in the new row.


Should:


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


No:


if (user.isHappy){  //Do something}else {  //Do something else}
    • There should be only one row between the methods, which makes it visually clearer and easier to organize. The whitespace within the method should be separated from the function, but is usually drawn out to become a new method.
    • Prefer to use auto-synthesis. But if necessary,@synthesizeand@dynamicshould declare a new row in each of the implementations.
    • You should avoid calling methods in a colon-aligned manner. Because sometimes a method signature may have more than 3 colons and colon alignments, the code is easier to read. Do not do this, although the colon-aligned method contains a block of code, because Xcode's alignment makes it illegible.


Should:


// blocks are easily readable
[UIView animateWithDuration:1.0 animations:^{
  // something
} completion:^(BOOL finished) {
  // something
}];


No:


// colon-aligning makes the block indentation hard to read
[UIView animateWithDuration:1.0
                 animations:^{
                     // something
                 }
                 completion:^(BOOL finished) {
                     // something
                 }];




Comments


When a comment is needed, the comment should be used to explain why This particular code is doing so. Any comments that are used must be kept up-to-date or deleted.



Block annotations are generally avoided because the code is as self-explanatory as possible, and comments are required only if there are intermittent or a few lines of code. exception: This does not apply to comments generated in the document





Named


Apple naming rules persist as much as possible, especially with these associated memory management rules (NARC).



Long, descriptive methods and variable names are good.



Should:


UIButton *settingsButton;


No:


UIButton *setBut;


A three-character prefix should often be named for classes and constants, but should be ignored in the entity name of core data. For official raywenderlich.com books, starter kits or tutorials, the prefix ' RWT ' should be used.



Constants should use a camel-like naming convention, with all the first letters capitalized and prefixed with the class name.



Should:


static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;


No:


static NSTimeInterval const fadetime = 1.7;


The property is also used in camel-style, but the first word of the first letter is lowercase. Use auto-synthesis for attributes instead of writing @ synthesize statements manually unless you have a good reason.



Should:


@property (strong, nonatomic) NSString *descriptiveVariableName;


No:


id varnm;




Underline


When using attributes, instance variables should be usedself.to access and change. This means that all properties will be visually different because they are in front of each otherself..



But there is one exception: in the initialization method, instance variables (for example, _variablename) should be used directly to avoid getters/setters potential side effects.



Local variables should not contain underscores.





Method


In a method signature, you should have a space after the method type (-/+ symbol). There should also be a space between each segment of the method (in Apple's style). You should include a descriptive keyword before the parameter to describe the parameter.



The use of the word "and" should be preserved. It should not be used for multiple parameters to illustrate, as ininitWithWidth:heightthe following example:



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;


No:


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




Variable


Variables should be named in a descriptive manner as much as possible. The name of a single character variable should be avoided, except in thefor()loop.



An asterisk indicates that the variable is a pointer. For example, theNSString *textNSString* textconstants are neither and notNSString * text, except for some special cases.



Private variables should be used as much as possible instead of instance variables. Although using instance variables is an efficient way, it is more inclined to use attributes to maintain code consistency.



Direct access to instance variables by using the ' Back ' property (_variable, preceded by an underscore in the variable name) should be avoided, except in the initialization method (,, etc...initinitWithCoder:),deallocmethods and custom setters and getters. For more information on how to use the accessor method directly in the initialization method and Dealloc, see here



Should:


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


No:


@interface RWTTutorial : NSObject {  NSString *tutorialName;}




Attribute Properties


All attribute attributes should be explicitly listed to help the novice read the code. The order of attribute attributes should be storage, atomicity, and automatically generated code when interface builder connects UI elements.



Should:


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


No:


@property (nonatomic, weak) IBOutlet UIView *containerView;@property (nonatomic) NSString *tutorialName;


NSString should be usedcopyinsteadstrongof attribute attributes.



Why? Even if you declare aNSStringproperty, someone might passNSMutableStringin an instance and then modify it without your attention.



Should:


@property (copy, nonatomic) NSString *tutorialName;


No:


@property (strong, nonatomic) NSString *tutorialName;




Dot symbol syntax


Point syntax is a convenient way to encapsulate access to method calls. When you use the DOT syntax, properties are still accessed or modified by using getter or setter methods. To learn more, read here



Point syntax should always be used to access and modify properties, because it makes the code more concise. [] symbols are more inclined to use in other examples.



Should:


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


No:


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




Literal value


NSString,NSDictionary,NSArray, andNSNumberthe literal value should be used when creating immutable instances of these classes. Please pay special attentionnilto values that cannot be passedNSArrayin and literalNSDictionary, because this will cause 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;


No:


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];




Constant


Constants are easy to re-use and can be quickly modified without the need to find and replace them. Constants should bestaticdeclared instead#defineof used, unless the macro is explicitly used.



Should:


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


No:


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




Enum type


When usedenum, it is recommended to use the new fixed base type specification as it has stronger type checking and code completion. The SDK now has a macroNS_ENUM()to help and encourage you to use a fixed base type.



For example:


typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {  RWTLeftMenuTopItemMain,  RWTLeftMenuTopItemShows,  RWTLeftMenuTopItemSchedule};


You can also assign values explicitly (show the old K-style constant definition):


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


The old K-style constant definition should be avoided unless you write code for core Foundation C.



No:


enum GlobalConstants {  kMaxPinSize = 5,  kMaxPinCount = 500,};




Case statement


Curly braces are not required in case statements unless the compiler enforces the requirements. When a case statement contains multiple lines of code, the curly braces should be added.


switch (condition) {
  case 1:
    // ...
    break;
  case 2: {
    // ...
    // Multi-line example using braces
    break;
  }
  case 3:
    // ...
    break;
  default: 
    // ...
    break;
}


Many times, when the same code is used by multiple cases, a fall-through should be used. One fall-through is to remove the ' break ' statement at the end of the case, allowing the execution process to jump to the next value. For the code to be clearer, a fall-through needs to be commented out.


switch (condition) {
  case 1:
    // ** fall-through! **
  case 2:
    // code executed for values 1 and 2
    break;
  default: 
    // ...
    break;
}


The ' default ' is not required when using the enum type with switch. For example:


RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;

switch (menuType) {
  case RWTLeftMenuTopItemMain:
    // ...
    break;
  case RWTLeftMenuTopItemShows:
    // ...
    break;
  case RWTLeftMenuTopItemSchedule:
    // ...
    break;
}




Private properties


Private properties should be declared in class extensions (anonymous classification) in the implementation file of the class, and named classifications (such asRWTPrivateorprivate) should never be used unless the other classes are extended. Anonymous categorization should be exposed to the test by using a naming convention that uses the


For example:


@interface RWTDetailViewController ()

@property (strong, nonatomic) GADBannerView *googleAdView;
@property (strong, nonatomic) ADBannerView *iAdView;
@property (strong, nonatomic) UIWebView *adXWebView;

@end




Boolean value


Objective-c useYESandNO. Becausetrueandfalseshould only be used in corefoundation,c or C + + code. Sincenilparsing is madeNO, there is no need to compare in conditional statements. Do not take something directly with theYEScomparison, because itYESis defined as 1 and oneBOOLcan be set to 8 bits.



This is to be considered in order to maintain consistency in different documents and to be more visually concise.



Should:


if (someObject) {}if (![anotherObject boolValue]) {}


No:


if (someObject == nil) {}if ([anotherObject boolValue] == NO) {}if (isAwesome == YES) {} // Never do this.if (isAwesome == true) {} // Never do this.


If theBOOLname of the property is an adjective, the attribute can ignore the "is" prefix, but specify the customary name of the get accessor. For example:


@property (assign, getter=isEditable) BOOL editable;


Text and examples from here refer to cocoa naming guidelines





Conditional statements


The conditional statement body should be surrounded with curly braces in order to prevent errors, even if the conditional statement body can be written without curly braces (for example, with just one line of code). These errors include adding a second line of code and expecting it to be an if statement; Also, even more dangerous defect can occur in an if statement where a 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's easier to read.



Should:


if (!error) {  return success;}


No:


if (!error)  return success;


Or


if (!error) return success;




Ternary operator


Ternary operators are used when it is necessary to improve the clarity and simplicity of the code?:. A single conditional evaluation often requires it. When multiple criteria are evaluated, the code is more readable if you useifa statement or re-form an instance variable. In general, it is best to use the ternary operator when assigning values based on conditions.



Non-boolean variables are compared to something, and parentheses () improve readability. If the variable being compared is a Boolean type, then no parentheses are required.



Should:


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


No:


result = a > b ? x = c > d ? c : d : y;




Init method


The Init method should follow the naming rules for Apple-generated code templates. The return type should be usedinstancetypeinstead ofid


- (instancetype)init {  self = [super init];  if (self) {    // ...  }  return self;}


View articles about Instancetype class Constructor Methods





Class construction methods


When a class construction method is used, it should return the type to beinstancetypeinstead ofid. This ensures that the compiler correctly infers the result type.


@interface Airplane+ (instancetype)airplaneWithType:(RWTAirplaneType)type;@end


For more instancetype information, please see nshipster.com





CGRect function


When accessedCGRect,,xywidth, orheightwhen, it should be accessed using aCGGeometryfunction rather than directly through the struct. References to AppleCGGeometry:


All functions in this reference document accept CGRect as input and implicitly standardize these rectangles when calculating their results. Therefore, your application should avoid directly accessing and modifying the data stored in the CGRect structure. Instead, use these functions to manipulate the rectangles and get their attributes.


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);


No:


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 };




Golden Path


When using conditional statement encoding, the left-hand side code should be "golden" or "Happy" path.ifthat is, do not nest statements, multiple return statements are OK.



Should:


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


No:


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




Error handling


When the method returns an error parameter by reference, the return value is judged instead of the error variable.



Should:


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


No:


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


In the case of success, some Apple APIs record the garbage value (garbage values) to the error parameter (if non-null), then judging the error value results in false negative values and crash.





Single-Case 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 prevents possible and sometimes prolific crashes.





Line break


Line breaks are an important topic because the style guides are primarily for printing and for readability on the web.



For example:


self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];


A long line of code should be divided into two lines of code and the next line separated by two spaces.


self.productsRequest = [[SKProductsRequest alloc]   initWithProductIdentifiers:productIdentifiers];




Xcode Project


Physical files should be synchronized with the Xcode project file to avoid file expansion. The creation of any Xcode grouping should be reflected in the file system file. The code is not only grouped by type , but can also be grouped by function , which makes the code clearer.



Open the "Treat Warnings as Errors as possible at Target's build settings, and enable the following additional Warnings. If you need to ignore special warnings, use Clang ' s pragma feature.


Other OBJECTIVE-C Coding Specifications


If our coding specifications don't match your tastes, you can look at other coding specifications:


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


From: http://www.jianshu.com/p/8b76814b3663?utm_campaign=hugo&utm_medium=reader_share&utm_content=note# Ternary-operator



raywenderlich.com OBJECTIVE-C Coding Specification


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.