iOS学习笔记二——OC代码规范(上)

文章目录

一、规范格式

1.1 规范的head file格式

@interface的body内的结构为:

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 规范的source file格式

#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

二、命名要求

2.1 功能明确

例如:insertObject,removeObjectAtIndex,setBackgroundColor,完整地体现事件过程,避免出现命名模糊的现象;

不规范命名:insert,setBkgdColor;

2.2 保持一致性

若有一个方法或属性出现在不同的类中,那么它们使用相同的标识符是有必要的,这种做法能体现出它们之间的关联,也有利于多态(polymorphism)的实现;

例如:

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

2.3 使用前缀

来自同一个package或framework,使用同一个前缀,由于2个字符的前缀被apple保留,一般使用最少三个字符的前缀;

由于OC没有namespace,因此采用在类名和方法名前加上前缀的方法,能有效避免命名冲突;

例如:
NS:Foundation;
NS:Application Kit;
AB:Address Book;

2.4 排版惯例

将多个单词的首字母大写,其余字母小写,然后放在一起,这种方式被称为驼峰式;

小驼峰式:对于方法名和变量名,首字母小写,其余规则不变,例如:fileExistAtPath;

大驼峰式:对于类名,除前缀外,首字母大写,其余规则不变,例如:NSRunAlertPanel;

2.5 Class和Protocal

Class要求名词性命名,例如NSScanner,UIApplication;

为了和Class做区分,Protocal通常以X-ing的形式命名,例如NSLocking;

2.6 文件名后缀

Extension type
.h C/C++/Objective-C 头文件
.m Objective-C 源代码文件
.mm C/C++/Objective-C 源代码文件,可以使用C++特性
.cc C++源代码文件
.c C源代码文件

三、命名规则

3.1 方法和成员命名

返回值为object,使用与该object类型相关的名词作为前缀,例如:

GOOD:-(Sandwich *)sandwich;

AVOID:-(Sandwich *)makeSandwich);

返回值为BOOL类型,方法命名要求把is作为前缀,例如:

-(BOOL)isGlorious;

约定:成员的getter方法名为它本身,而不需要额外的get作为前缀,例如:

GOOD:-(id)delegate;

AVOID:-(id)getDelegate;

尽量避免直接使用成员变量,而是使用getter方法:

GOOD:NSEnumerator *enumerator = [frogs reverseObjectEnumerator];

AVOID:NSEnumerator *enumerator = frogs.reverseObjectEnumerator;

3.2 global变量

对于声明在方法和类之外的global变量,使用g作为前缀标识,并尽量少地使用;

Example: gGlobalCounter;

3.3 枚举型变量

声明的每个枚举成员都应该具有相同的前缀:与枚举标识符相同,即使不使用namespace,这种做法也可以有效避免冲突;

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

3.4 局部变量

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

在ARC下,强指针和弱指针都自动声明为nil,然而,大多数的指针不具有ARC的特性,不会被初始化,因此最好在声明时就进行初始化操作,而不是先声明,再初始化;

3.5 整型无符号数

为了防止数学运算中出现细微的误差,在计算前需要把无符号整型数进行转化,把它们变为signed integer来使用;

// 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 不同位数下的变量类型

long, NSInteger, NSUInteger, 和CGFloat在32位和64位系统下的size不同,在赋值时需要考虑位数的影响;

// GOOD:

int32_t scalar1 = proto.intValue;

int64_t scalar2 = proto.longValue;

NSUInteger numberOfObjects = array.count;

CGFloat offset = view.bounds.origin.x; 

四、总结

资料地址:

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

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

上一篇:从OC到Swift(8) - 多线程


下一篇:mysql – azk – 如何设置测试数据库?