preface

Objective-c language is mainly used for iOS and Mac development. This paper combines Apple’s and Google’s specifications with a series of coding specifications summed up by my own personal experience. Apple Objective – C specification: developer.apple.com/library/mac… Google Objective – C specification: zh-google-styleguide.readthedocs.org/en/latest/g…

Code indentation and line code

There are two specifications for indenting code for Apple and Google: Apple is indented with 4 Spaces and Google with 2 Spaces. In this case, we use the Apple specification of four Spaces for indentation, but we can’t use the TAB character, so in Xcode we set TAB for four Spaces (see Figure 1), and use the TAB key for indentation instead of typing the Spaces ourselves.

Header file import

1. Use #import when importing Objective-C or Objective-C++ headers, and #include 2 when importing C or C++ headers. When importing the system API, you should refer directly to the root header file, not the submodule header file. Even if you use only a small part of it, the compiler will automatically optimize it. Each framework has a header file with the same name as the framework, which contains all references to the interfaces within the framework. Such as:

// Correct:#import <UIKit/UIKit.h>// Error#import <UIKit/UIButton.h>
Copy the code

3. Use #import <> format when importing system apis 4. Use #import <> format 5 when importing third-party frameworks. Use #import “” format 6. Place a space between import and other file names. If there is more than one import statement, group the statements. Comments for each group are optional. Note: Use #import syntax for modules. In addition to subclassing or protocols, it is best to use @class to avoid excessive header files. When importing a protocol, if the current class is not also imported, declare the protocol separately and then import it.

Naming conventions

The basic principle of

All naming must be in English, naming should be as clear and concise as possible. In Objective-C, clear naming is more important than brevity.

Naming notification names and other keys must be in English!

/ / correct nsstrings * kLogoutSuccessNotification = @"LogoutSuccessNotification"; / / error nsstrings * kLogoutSuccessNotification = @"Log out";
Copy the code

All modifiers such as =, +, -, &, | must leave a space on both sides

InsertObject :atIndex: insertObject:atIndex: insertObject:atIndex:Copy the code

But there are some abbreviations that are very common in Objective-C coding, such as:

alloc == Allocate 
init == Initialize 
max == Maximum
min == Minimum
alt == Alternate 
app == Application 
msg == Message
calc == Calculate 
nib == Interface Builder archive
dealloc == Deallocate 
pboard == Pasteboard
func == Function 
rect == Rectangle
horiz == Horizontal 
vert == Vertical
Rep == Representation 
info == Information 
temp == Temporary
Copy the code

consistency

Keep the naming style consistent throughout the project, preferably with the Apple SDK code. Methods that perform similar functions in different classes should have the same name. For example, we always use count to return the number of sets. We cannot use count in class A and getNumber in class B

The prefix

Apple reserves the right to use all two-letter prefixes, so in order to prevent conflicts with official apis, all files in the project must have three (or more) uppercase prefixes.

You can use prefixes when naming classes, protocols, functions, constants, and typedef macros, but be careful not to use prefixes for member variables or methods, because they are inherently contained in the class namespace.

Named properties or instance variables

When defining a property, the compiler automatically generates thread-safe access methods (Atomic), but this can greatly degrade performance, especially for properties that require frequent access and can be wasteful. So if you define a property that does not require thread protection, remember to manually add the property keyword nonatomic to de-optimize the compiler.

Variable names should be as descriptive as possible. Single-letter variable names should be avoided in all cases except for for loops. Asterisks denote pointer property variables, such as NSString text Do not write NSString text or NSString * text, except for constants.

Instead of using instance variables directly, try to define attributes and declare how memory is managed. If a property is set only once in the init method, declare it readonly. The format is as follows:

@property (nonatomic, strong) ClassName *name;
Copy the code

Note: 1. After @property there is a space. 2. There is a space between the class name and “) “4. If it is an object type, the property name is accompanied by * and separated by a space from the class name

Copy is used when defining NSString and Block types. When defining basic data types, use the weak, format when defining proxy objects using assign

@property(nonatomic, weak) id <UIAlertViewDelegate> delegate; When you define an object type using strong to define a BOOL attribute, you should indicate a getter methodCopy the code

// error @property (nonatomic, assign) BOOL isShow; @property (nonatomic, assign, getter=isShow) BOOL show;

There are two ways to define variables:Copy the code

NSData *_data; } // error {NSData *data; }

@property (nonatomic, strong) NSData *data;Copy the code

The second method is recommended because it generates getter and setter methods by default

Naming Methods

Objective-c method names are often long to make programs more readable, and according to Apple, “good method names should be read aloud as a sentence.”

In the method signature, there should be a space after the -/+ symbol. There should also be a space between method fragments. The constructor makes InstanceType the return type instead of ID.

For private methods, you should prefix them. It is recommended to use the underlined p as p_, where P stands for “private”. It is not recommended to use a single underlined p, which is reserved for Apple.

Methods generally start with a lowercase letter, each subsequent word begins with a capital letter, and method names should not have punctuation marks (including underscores), with two exceptions:

You can use some common capital initials, such as PDF,TIFF, etc. You can name private methods or methods in a category with an underlined prefix. If the method tells the object to perform an action, name it with a verb. Be careful not to use redundant keywords like do and does. The verb itself is suggestive enough:

// the verb begins with an action - (void)invokeWithTarget:(id)target; - (void)selectTabViewItem:(NSTabViewItem *)tabViewItem;Copy the code

If the method is to get the value of a property of an object, name the method with the property name. Be careful not to add get or other verb prefixes:

// Correct, use the attribute name to name the method - (NSSize)cellSize; // error, add extra verb prefix - (NSSize)calcCellSize; - (NSSize)getCellSize;Copy the code

For methods with multiple parameters, add a keyword before each parameter. The keyword should clearly state the function of the parameter:

- (void)sendAction:(SEL)aSelector toObject:(id)anObjectforAllCells:(BOOL)flag; - (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; // correct - (id)viewWithTag:(NSInteger)aTag; - (id)taggedView:(int)aTag;Copy the code

Do not concatenate two parameters with AN and, which is usually used to indicate that the method performs two relatively independent operations (by design, this should be split into two separate methods) :

// Error, do not use"and"- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; // Correct, use"and"- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;Copy the code

Method parameter names also have a few caveats:

Do not use pointer, PTR, etc. The type of the argument is sufficient. Do not use one or two letter parameter namesCopy the code

Here are some common parameter names:

. action:(SEL)aSelector ... alignment:(int)mode ... atIndex:(int)index ... content:(NSRect)aRect ... doubleValue:(double)aDouble ... floatValue:(float)aFloat ... font:(NSFont *)fontObj ... intValue:(int)anInt ... keyEquivalent:(NSString *)charCode ... point:(NSPoint)aPoint ... stringValue:(NSString *)aString ... target:(id)anObjectCopy the code

Name the base data type

For 32-bit and 64-bit compatibility, use the data types provided by the Apple SDK when defining basic data types

int -> NSInteger
unsigned -> NSUInteger
float-> CGFloat double -> CGFloat animation time -> NSTimeInterval...Copy the code

Named Delegate

When a particular event occurs, the object fires the proxy method it registers. Proxies are a common way of passing messages in Objective-C. Agents have their own fixed naming patterns.

The first argument to a proxy method is the object that triggered it, and the first keyword is the name of the class that triggered it, unless the proxy method has only one argument called sender:

- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row; - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename; // When there is only one"sender"Parameter can be omitted when the name of the class - (BOOL) applicationOpenUntitledFile (NSApplication *) sender; // use should,will,did, etc. - (void)browserDidScroll:(NSBrowser *)sender; - (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window; , - (BOOL) windowShouldClose (id) sender;Copy the code

Named Constants

Do not use the #define macro to define constants. #define is usually used by the compiler to decide whether to compile a block of code, such as the common:

#ifdef DEBUG
Copy the code

Use const to define basic data types or string constants. Constants are named the same as functions, but constants are usually called k:

A private class is defined as follows:

static const CGFloat xxxx
static NSString *const title
Copy the code

If we define a common constant as follows:

H file: extern NSString *const title; .m file: NSString *const title = @"title";
Copy the code

Named Notifications

Notifications are often used to pass messages between modules, so notifications should represent events as closely as possible. The naming paradigm for notifications is:

[the class name of the trigger notifications] + [Did | Will] + [action] + Notification such as:  NSApplicationDidBecomeActiveNotification NSWindowDidMiniaturizeNotification NSTextViewDidChangeSelectionNotification NSColorPanelColorDidChangeNotificationCopy the code

Code specification

Do not use the new method

Although you can often use new instead of the alloc init method, this can cause unexpected problems when debugging memory. The Cocoa specification uses the alloc init method, and using new can be confusing for some readers.

Use of new syntax

In objective-C’s new syntax, the.h declaration class should add NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END with Spaces above and below @interface and @end.

NS_ASSUME_NONNULL_BEGIN

@interface APPTextView : UIView

@end

NS_ASSUME_NONNULL_END
Copy the code

NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END add nonNULL to attribute and method arguments and return values by default. If you determine that an attribute or method argument can be null, add the nullable modifier

The use of the BOOL

BOOL is defined in Objective-C as signed char, which means that a BOOL variable can represent more than just YES(1) and NO(0), so never compare a BOOL variable to YES directly:

/ / error, can not be sure | great | value is YES (1), don't compare Boolean value directly with YES BOOL great = [foo isGreat];if(great == YES) // ... be great! // correct BOOL great = [foo isGreat];if(great) // ... be great!Copy the code

Similarly, do not return any other type of value as BOOL, in which case the BOOL variable is assigned only to the last byte of the value, which is likely to reach 0 (NO). However, some logical operators such as &&, | |,! The return of BOOL can be assigned directly to BOOL:

// Error, do not convert other types to BOOL Returned - (BOOL)isBold {return [self fontTraits] & NSFontBoldTrait;
}
- (BOOL)isValid {
return[self stringValue]; } // Correct - (BOOL)isBold {return([self fontTraits] & NSFontBoldTrait) ? YES : NO; } // The Boolean operator can be directly converted to BOOL - (BOOL)isValid {return[self stringValue] ! = nil; } - (BOOL)isEnabled {return [self isValid] && [self isBold];
}
Copy the code

Use of logical judgment

If else, {} must be added, whether the statement is one sentence or more. The judgment should first filter out the incongruent logic and then deal with the important logic. If the judgment execution logic is return, {} can not be written, but return must be in the line with the judgment statement to prevent errors. Such as:

if(Judgment statement)return;
Copy the code

More often than not

if(judgment) {// logic code}else{// logic code}Copy the code

Don’t leave judgment unexecuted

/ / errorif (i == 3) {

} else{// execute logic} // Correctif(i ! = 3) {// execute logic}Copy the code

Do not use accessor methods to access instance variables in init and dealloc

The runtime environment of the class is not in a normal state when the init Dealloc method is executed, and accessing variables using access methods can lead to unexpected results, so instance variables should be accessed directly within both methods.

- (instanceType)init {self = [super init];if (self) {
  _bar = [[NSMutableString alloc] init];
 }
 returnself; } - (void)dealloc { [_bar release]; [super dealloc]; } // error, do not access method access - (instanceType)init {self = [super init];if (self) {
  self.bar = [NSMutableString string];
 }
 return self;
}
- (void)dealloc {
 self.bar = nil;
 [super dealloc];
}
Copy the code

Make sure that NSString is copied on assignment

NSString is very common, and when it is passed or assigned, it should be copied. This prevents the String value from being modified by other objects without your knowledge.

- (void)setTitle:(NSString *)aTitle {
 _title = [aTitle copy];
}
Copy the code

Nil checks

Since sending commands to nil objects in Objective-C doesn’t throw an exception or cause a crash, it’s just a complete “do nothing,” so use nil only in programs for logical checks.

Also, don’t use forms such as nil == Object or Object == nil.

// Correct, direct judgmentif(! objc) { ... } // error, do not use the form nil == Objectif (nil == objc) {
 ...
}
Copy the code

Naming the enumeration

Enumerations are strongly recommended to replace magic numbers with enumerations (three important things to mention) and enumerations need to be commented properly. Enumerations are defined in Objective-C syntax preferred, in the following format:

Typedef NS_ENUM (NSInteger, QZGProfile) {QZGProfileIDCard = 0, < enumeration comment};Copy the code

Any enumerations that need to be combined by bits or operations should be defined using NS_OPTIONS.

Typedef NS_OPTIONS(NSUInteger, OKState) {OKState1 = 1 << 0, OKState2 = 1 << 1};Copy the code

The magic number

Magic numbers should be avoided as much as possible, and enumerations should be used if a set of data is present. If tag is used, it is recommended to use char because character types correspond to numbers in the ASCII table, such as ‘A’,’b’, etc., but set to A maximum of four characters, such as ‘ABCD’.

other

Do not add Spaces between the object type and protocol.

// recommend: @property (nonatomic, weak) id<OKDelegate> delegate; // Object: @property (nonatomic, weak) id <OKDelegate> delegate;Copy the code

The Xcode project

To avoid file clutter, physical files should be kept in sync with Xcode project files. Any group created by Xcode must have a mapping on the file system. For clarity, code should be grouped not only by type, but also by functionality.

annotation

Good code is self-documenting, but detailed comments are needed to explain what the parameters mean, what they return, what they do and what side effects they may have. The definition of methods, functions, classes, protocols and categories all need annotations. It is recommended to use Apple’s standard annotation style. The advantage is that you can automatically pop up annotations by Alt + clicking on the reference place, which is very convenient. VVDocumenter is recommended

File comment

File comments are placed at the head of the.h file in the format:

// @brief specifies the functionality of the class /// @since which APP version was used from /// @author who recently changed the codeCopy the code

Attribute note

1. If you use too much formatting for comment content:

*/ @property (nonatomic, strong) ClassName *name;Copy the code

2. When there is not much content in the comment, the comment uses /// or //! “Format:

@property (nonatomic, strong) ClassName *name;Copy the code

or

@property (nonatomic, strong) ClassName *name; / /! < Comment contentCopy the code

Methods the annotation

1. Method comments should be used in the.h life class

/** * method Function ** @param Parameter Description ** @returnThe return value description * / or / / method/function / / / / / / @ param parameter specifies / / / / / / @returnReturn Value DescriptionCopy the code

It is recommended to add a comment with VVDocumenter, or /// if the method comment has only one line

In the. M implementation class, you should use #pragma mark – to comment the content or #pragma mark to comment the content

Warnings and Errors

I write about warnings and errors specifically, because I think warnings and errors should be given due attention. There’s not much to say about errors, but if you write code that makes a mistake, Xcode can’t watch it, so Xcode will give you a hint to fix it. For warnings, the final code submitted by a good programmer should not contain any warnings, so we should try to fix them when we write them. You can use it if you can’t avoid it

#pragma clang diagnostic push
Pragma Clang Diagnostic ignored "Warning type"// Warning content to ignore#pragma clang diagnostic pop
Copy the code

This is a way to disarm the warning, but it should not be abused unless you are absolutely certain that the warning will do little harm to the project.

conclusion

No rules, no fangyuan, I hope this article can help you. I will update from time to time, if there is any objection, please issue me.