iOS Learning Notes II - OC Code Specification

Keywords: REST Attribute github Google

Articles Catalogue

I. Normative Format

Headfile format of 1.1 specification

@ The structure of the body of the interface is as follows:

properties;

class methods;

initializers;

instance methods.

#import <Foundation/Foundation.h>

@class Bar;

/**
 * A sample class demonstrating good Objective-C style. All interfaces,
 * categories, and protocols (read: all non-trivial top-level declarations
 * in a header) MUST be commented. Comments must also be adjacent to the
 * object they're documenting.
 */
@interface Foo : NSObject

/** The retained Bar. */
@property(nonatomic) Bar *bar;

/** The current drawing attributes. */
@property(nonatomic, copy) NSDictionary<NSString *, NSNumber *> *attributes;

/**
 * Convenience creation method.
 * See -initWithBar: for details about @c bar.
 *
 * @param bar The string for fooing.
 * @return An instance of Foo.
 */
+ (instancetype)fooWithBar:(Bar *)bar;

/**
 * Initializes and returns a Foo object using the provided Bar instance.
 *
 * @param bar A string that represents a thing that does a thing.
 */
- (instancetype)initWithBar:(Bar *)bar NS_DESIGNATED_INITIALIZER;

/**
 * Does some work with @c blah.
 *
 * @param blah
 * @return YES if the work was completed; NO otherwise.
 */
- (BOOL)doWorkWithBlah:(NSString *)blah;

@end

1.2 Specification source file format

#import "Shared/Util/Foo.h"

@implementation Foo {
  /** The string used for displaying "hi". */
  NSString *_string;
}

+ (instancetype)fooWithBar:(Bar *)bar {
  return [[self alloc] initWithBar:bar];
}

- (instancetype)init {
  // Classes with a custom designated initializer should always override
  // the superclass's designated initializer.
  return [self initWithBar:nil];
}

- (instancetype)initWithBar:(Bar *)bar {
  self = [super init];
  if (self) {
    _bar = [bar copy];
    _string = [[NSString alloc] initWithFormat:@"hi %d", 3];
    _attributes = @{
      @"color" : [UIColor blueColor],
      @"hidden" : @NO
    };
  }
  return self;
}

- (BOOL)doWorkWithBlah:(NSString *)blah {
  // Work should be done here.
  return NO;
}

@end

Naming requirements

2.1 Clear Function

For example: insertObject, removeObjectAtIndex, setBackgroundColor, fully reflect the event process, to avoid the phenomenon of naming ambiguity;

Irregular naming: insert, setBkgdColor;

2.2 Consistency

If a method or attribute appears in different classes, it is necessary for them to use the same identifier, which can reflect the association between them, and is also conducive to the implementation of polymorphism.

For example:

-(NSInteger)tag;
-(void)setStringValue:(NSString*);

2.3 Use prefixes

From the same package or framework, the same prefix is used. Because the prefix of two characters is reserved by apple, the prefix of at least three characters is usually used.

Because OC has no namespace, the method of prefixing class name and method name can effectively avoid naming conflicts.

For example:
NS: Foundation;
NS: Application Kit;
AB: Address Book;

2.4 typesetting conventions

The way of capitalizing the initial letters of multiple words and lowering the remaining letters and putting them together is called hump.

Hump: For method names and variable names, the first letter is lowercase, and the rest of the rules remain unchanged, such as fileExistAtPath;

Big Hump: For class names, the first letter is capitalized except for the prefix, and the rest of the rules remain unchanged, for example: NSRun Alert Panel;

2.5 Class and Proocal

Class requires nominal naming, such as NSScanner, UIApplication;

To distinguish it from Class es, Protocal is usually named in the form of X-ing, such as NSLocking.

2.6 File Name Suffix

Extension type
.h C/C++/Objective-C header file
.m Objective-C source code file
.mm C/C++/Objective-C source code files, using C++ features
.cc C++ source code file
.c C source code file

Naming Rules

3.1 Method and Membership Naming

The return value is object, prefixed by nouns associated with the object type, such as:

GOOD: -(Sandwich *)sandwich;

AVOID: -(Sandwich *)makeSandwich);

The return value is of BOOL type, and method naming requires that is be prefixed, for example:

-(BOOL)isGlorious;

Convention: The member's getter method is named itself, without the need for additional gets as prefixes, such as:

GOOD: -(id)delegate;

AVOID: -(id)getDelegate;

Instead of using member variables directly, try to use the getter method:

GOOD: NSEnumerator *enumerator = [frogs reverseObjectEnumerator];

AVOID: NSEnumerator *enumerator = frogs.reverseObjectEnumerator;

3.2 global variable

For global variables declared outside methods and classes, g is used as a prefix identifier and as little as possible.

Example: gGlobalCounter;

3.3 Enumerative Variables

Each enumeration member declared should have the same prefix: the same as the enumeration identifier, which can effectively avoid conflicts even if namespace is not used;

typedef NS_ENUM(NSInteger, DisplayTinge) {
  DisplayTingeGreen = 1,
  DisplayTingeBlue = 2,
};

3.4 Local Variables

// GOOD:

CLLocation *location = [self lastKnownLocation];
for (int meters = 1; meters < 10; meters++) {
  reportFrogsWithinRadius(location, meters);
}

// AVOID:

int meters;                                         // AVOID.
for (meters = 1; meters < 10; meters++) {
  CLLocation *location = [self lastKnownLocation];  // AVOID.
  reportFrogsWithinRadius(location, meters);
}

In ARC, strong pointers and weak pointers are automatically declared as nil. However, most pointers do not have the characteristics of ARC and will not be initialized. Therefore, it is better to initialize them when they are declared, rather than declare them first and then initialize them.

3.5 integer unsigned number

In order to prevent subtle errors in mathematical operations, unsigned integers need to be converted into signed integers before calculation.

// GOOD:
NSUInteger numberOfObjects = array.count;
for (NSInteger counter = numberOfObjects - 1; counter > 0; --counter)

// AVOID:
for (NSUInteger counter = numberOfObjects - 1; counter > 0; --counter)  // AVOID.

3.6 Variable types in different digits

long, NSInteger, NSUInteger, and CGFloat are different in size under 32-bit and 64-bit systems. The influence of digits should be taken into account when assigning values.

// GOOD:

int32_t scalar1 = proto.intValue;

int64_t scalar2 = proto.longValue;

NSUInteger numberOfObjects = array.count;

CGFloat offset = view.bounds.origin.x; 

IV. SUMMARY

Information address:

https://github.com/google/styleguide/blob/gh-pages/objcguide.md;

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html

Posted by achild on Sun, 28 Jul 2019 06:40:38 -0700