Objective-C編碼規范


本文參考Apple & Google Objective-C編碼規范,根據個人的編碼習慣,總結出一些通用的編碼規則。

代碼示例

頭文件示例代碼

下面是用Objective-C語言編寫的規范的頭文件示例代碼。

//
//  BTFoo.h
//  CodingGuidelines
//
//  Created by Tracy E on 12-8-13.
//  Copyright (c) 2012年 ChinaMWorld Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

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

@interface BTFoo : NSObject{
  @private
    NSString *_bar;
    CGFloat _price;
    
  @public
    NSString *_name;
    id<BTFooDelegate> _delegate;
}
@property (nonatomic, copy) NSString *name;                 //the name of Foo. default is nil.
@property (nonatomic, assign) id<BTFooDelegate> delegate;   //weak reference. default is nil.

/**
 initializer. |string| will be copied and assigned to |_name|.
 @param string The foo name.
 @return an autorelease instance of BTFoo.
 */
- (id)initWithString:(NSString *)string;


/**
 Designated initailizer. initialize a new BTFoo object.
 @param name The model name.
 @param number The model number.
 @param price The model price.
 @return a newly initialized object.
 */
- (id)initFooWithModelName:(NSString *)name
               modelNumber:(NSUInteger)number
                modelPrice:(CGFloat)price;

/**
 Dosomething...
 @param name The model name.
 @param number The model number.
 @param price The model price.
 */
- (void)doName:(NSString *)name
    modelNumber:(NSUInteger)number
    modelPrice:(CGFloat)price;

//Gets and Sets |_bar|.
- (NSString *)bar;
- (void)setBar:(NSString *)bar;
@end

 

源文件示例代碼

下面是用Objective-C語言編寫的規范的源文件示例代碼。

//
//  BTFoo.m
//  CodingGuidelines
//
//  Created by Tracy E on 12-8-13.
//  Copyright (c) 2012年 ChinaMWorld Inc. All rights reserved.
//

#import "BTFoo.h"

@interface BTFoo (PrivateMethods)

+ (id)fooWithString:(NSString *)string;

@end

@implementation BTFoo
@synthesize name = _name;
@synthesize delegate = _delegate;

- (void)dealloc{
    [_bar release];
    [_name release];
    
    [super dealloc];
}

- (id)initWithString:(NSString *)string{
    self = [super init];
    if (self) {
        _name = [string copy];
        _bar = [[NSString alloc] initWithFormat:@"bar"];
    }
    return self;
}

- (id)initFooWithModelName:(NSString *)name
               modelNumber:(NSUInteger)number
                modelPrice:(CGFloat)price{
    self = [BTFoo fooWithString:name];
    if (self) {
        _price = price;
    }
    return self;
    
}

- (void)doName:(NSString *)name
    modelNumber:(NSUInteger)number
    modelPrice:(CGFloat)price{
    
}

- (NSString *)bar{
    return _bar;
}

- (void)setBar:(NSString *)bar{
    [_bar autorelease];
    _bar = [bar copy];
}

#pragma mark BTFoo Private Methods
+ (id)fooWithString:(NSString *)string{
    return [[[BTFoo alloc] initWithString:string] autorelease];
}

- (void)doSomethingWith:(BTFoo *)theFoo
                   rect:(CGRect)theRect
               interval:(float)theInterval{
    //...
}

- (void)short:(BTFoo *)theFoo
    longKeyword:(CGRect)theRect
    evenLongerKeyword:(float)theInterval{
    //...
}
@end

 

間距與格式

程序中代碼的排版,縮進,間隔等可以根據IDE的具體設置而決定,但最終都應該使代碼的間距與格式統一,達到整齊美觀的效果。

指針的位置

類型與“*”之間一個空格,“*”與變量名之間沒有空格。

NSString *_text;

每行代碼的長度

每行代碼的長度不超過100個字符。每行代碼的字符數可通過IDE進行設置。(設置:XCode —> Preferences —> Text Editing —> Page guide at column : 100)

方法的聲明與定義

聲明方法時,在 - 或 + 與返回類型之間應該留一個空格的間距。參數表的參數之間不要留間隔。

星號(*)前的空格是必須的。

- (id)initWithString:(NSString *)string;

如果參數過多,每個參數應各占一行。在有多行參數的情況下,每行參數前的冒號應對齊。

- (void)doSomethingWith:(BTFoo *)theFoo
                   rect:(CGRect)theRect
               interval:(float)theInterval{
    //...
}

當第一行的函數關鍵字比其后面行的關鍵字短時,后面的行應縮進四個空格。保證后續的關鍵字垂直對齊,而不應該采用冒號對齊的方式。

- (void)short:(BTFoo *)theFoo
    longKeyword:(CGRect)theRect
    evenLongerKeyword:(float)theInterval{
    //...
}

方法的調用

如果調用的方法沒有超出一行(100字符長),則所有參數在同一行。

[item1 setTitle:@"提交" forState:UIControlStateNormal];

如果調用的方法過長,則每個參數占用一行,以冒號對其。

    [button addTarget:self
               action:@selector(buttonPressed:)
     forControlEvents:UIControlEventTouchUpInside];

如果調用的方法過長,但方法名比參數名短,每個參數一行,縮進四個空格豎直對齊。

[self short:myFoo
    longKeyword:rect
    eventLongerKeyword:10];

@public 與 @private的使用

使用權限控制符@public 和@private 應縮進兩個空格。

@interface MyClass : NSObject{
  @private
    NSInteger _count;

  @public
    NSString *_title;
}
@end

協議的使用

在類型標識符與協議的名之間不應該有空格。此協議使用的規范適用於類的聲明、成員變量的聲明以及方法的聲明

@protocol MyClassDelegate;
@interface MyClass : NSObject{
  @private
    id<MyClassDelegate> _delegate;
}
@property (nonatomic, assign) id<MyClassDelegate> delegate;

如果申明中包含多個protocal且超出一行時換行,縮進兩個空格。

@interface CustomViewController : UIViewController<UITableViewDataSource, UITableViewDataSource,
  UITextFieldDelegate, UISearchBarDelegate>{

}

@property,@synthesize,@dynamic的使用

@property與左括號之間留一個空格。

@property和@synthesize的縮進級別與@interface或者@implementation的縮進級別相同。

@property的聲明語句應該緊跟在類的成員變量聲明語句塊的后面。

@synthesize的實現語句應該緊跟在@implementation語句之后。

@interface BTAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

@implementation BTAppDelegate
@synthesize window = _window;

命名規范

文件的命名

文件的名字應該反映其中包含的類名字,也應該遵循項目的風格習慣。

文件擴展命的使用規范如下:

.h C/C++/Objective-C頭文件
.m Objective-C源文件
.mm Objective-C++源文件
.cc 純C++源文件
.c C源文件

類的命名

類名應該用大寫開頭的駝峰命名法。

MyTableView、HomeViewController 

在應用程序級別的代碼中,盡量不要使用帶前綴的類名。每個類都有相同的前綴不能提高可讀性。如果是編寫多個應用程序間的共用代碼,那么需要為類名加上前綴。

Category的命名

Category的命名應該包含2-3個字符的前綴,用於說明Category是屬於具體的某個工程的。

當聲明一個Category時,Category的左括號與類名之間應該留一個空格的間隔。

例如要實現NSString的一個Category,用於實現解析功能。Category的文件名應該命名為NSString+GTMParsing.h,而Category的名字為GTMStringParsingAdditions,Category的名字與文件名不一致的原因是,在NSString+GTMParsing.h的文件中,可以聲明多個用於解析功能的NSString類的Category。

Objective-C方法命名

1.方法應使用小寫開頭的駝峰法命名,每個參數都應該小寫開頭。

2.方法名應該盡可能讀起來像一句話,參數名就如同方法名的補充說明(比如convertPoing:fromRect: 或者 replaceCharactersInRange:withString: )。

3.方法明中要避免單詞縮寫。

- (void)setBGImage:(UIImage *)img;              //避免
- (void)setBackgroundImage:(UIImage *)image;    //推薦

變量的命名

變量名應使用小寫開頭的駝峰法命名。

類成員變量名應該以一個下划線開始。

常量(預定義,枚舉,局部常量等)使用小寫k開頭的駝峰法。例如:

 localVariable;            //局部變量
 _instanceVariable;    //成員變量
 kConstant;                //常量

注釋

文件的注釋

每個文件的開頭都應該包含以下的注釋。

1.文件名。

2.項目名稱。

3.文件的創建者。

4.創建日期。

5.版權說明。

6.必要時還應包含許可聲明。(如:Apache 2.0, BSD, LGPL, GPL)

聲明的注釋

對每個接口,類別,協議進行聲明時,都應該有用於解釋其功能或者如何使用的注釋。

每個方法/函數聲明時,都應該有用於解釋其功能,參數值,返回值的注釋,必要時還應該說明方法/函數的使用注意事項。

當類的成員變量可用於多線程訪問時,應該對其使用做出詳細的說明和解釋。

//A delegate for NSApplication to handle notifications about app
//launch and shut down. Owned by the main app controller.
@interface AyAppDelegate : NSObject{

}
@end

實現的注釋

在為接口,類別,協議,方法/函數等的實現寫注釋時,應該使用豎線引用變量,函數名或者其他符號。

//Sometimes we need |count| to be less than zero.
//Remember to call |StringWithSpaces("foo bar baz")|

屬性的類型

應該嚴格的控制屬性的類型(readonly, copy, retain, assign)

不允許外部修改的屬性,使用readonly;

NSString類型使用copy而不是retain;

代理delegate使用assign,禁止使用retain。

注意事項

成員變量訪問權限

成員變量應該盡可能地定義為@private。

重寫指定初始化方法

當對一個類進行子類化時,一定要重寫父類的指定初始化方法。如果沒有正確重寫父類的指定初始化方法,子類的初始化方法可能不會被調用,這會導致很多微妙而難以預測的錯誤。

初始化

沒有必要在類的初始化方法中將成員變量的初始值設置為0或者nil。

     //都是多余的
     BOOL editable = NO;   
     NSInteger currentIndex = 0; 
     NSString *title = nil;

BOOL的使用

1.當將一個整型賦值給BOOL類型時應該特別注意,因為BOOL的類型為unsigned char。

2.不應該將BOOL類型的變量直接與YES進行比較

   if(editable){/*推薦*/ }
   if(editable == YES){/*不推薦*/} 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM