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.