命名的好壞在開發中每每也不怎麼重視,畢竟差的命名也不會影響程序邏輯。可是很差的命名在大項目中帶來的隱形維護成本是至關高的,這些在項目開始時可能還很難察覺,然後來會陷入前仆後繼的維護困境中。咱們每每很是重視項目邏輯的複雜性,卻不能好好的把「簡單」的命名作好。其實,若是簡單的東西都作很差,那麼作出再複雜的東西那也是垃圾。html
與類命名相同,此外需添加要擴展的類名和「+」ios
舉例:NSString+URLEncodinggit
與類命名相同,此外需添加「Delegate」後綴github
舉例:ReplyViewDelegateide
首字母小寫,以後每一個單詞首字母都大寫函數
方法名使用動詞短語動畫
舉例:- (void)setupPostWithValue:(int)valueui
「要什麼」每每被胡亂命名爲get
開頭的方法。首先get是一個動詞,因此它仍是「作什麼」或者說「作的是要什麼」。那麼get方法不要用於返回對象,但它可用於參數。編碼
- (XXItem *)getItemAtIndex:(NSUInteger)index //Bad!! 不規範的命名 - (XXItem *)itemAtIndex:(NSUInteger)index //Good, 命名清晰 - (void)getItem:(XXItem **)outItem atIndex:(NSUInteger)index //比較符合規範,但第二種更好。
首字母小寫,以後每一個單詞首字母都大寫atom
每一個參數前要加參數的名稱提示
舉例:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
採用修飾+類型的方式
舉例:
titleLabel //表示標題的label, 是UILabel類型 confirmButton //表示確認的button, 是UIButton類型
使用英文,所有小寫 ,添加模塊名做爲前綴,避免衝突 。圖片應該與類文件同樣,按模塊分組放置
舉例:
Home(界面名稱)_(功能屬性簡寫+描述).png
如: home_btn_recommended.png
或:
compose_mentionbutton_background@2x.png
compose_mentionbutton_background_highlighted@2x.png
使用英文,首字母大寫,以後每一個單詞首字母都大寫
每一個分組使用模塊的名字
使用的開源庫統一放在「Library」分組下
使用的公共組件統一放在「Common」分組下
使用資源統一放在"Resource"分組下,包括文件、音頻、圖片、證書等
編碼規範簡單來講就是爲了保證寫出來的代碼具有三個原則:可複用, 易維護, 可擴展. 這其實也是面向對象的基本原則. 可複用, 簡單來講就是不要寫重複的代碼, 有重複的部分要儘可能封裝起來重用。
推薦:
if (someObject) { ... } if (!someObject) { ... }
不推薦:
if (someObject == YES) { ...} if (someObject != nil) { ...}
if (someObject == YES)容易誤寫成賦值語句
推薦:
result = object ? : [self createObject];
不推薦:
result = object ? object : [self createObject];
若是是存在就賦值自己, 簡潔。
推薦:
BOOL isAdult = age > 18;
不推薦:
BOOL isAdult; if (age > 18) { isAdult = YES; } else { isAdult = NO; }
推薦:
if (car == Car.Nissan) or const int adultAge = 18; if (age > adultAge) { ... }
不推薦:
if (carName == "Nissan") or if (age > 18) { ... }
死值每次修改的時候容易被遺忘, 地方多了找起來就悲劇了. 並且定義成枚舉或者static可讓錯誤發生在編譯階段. 另外僅僅看到一個數字, 徹底不知道這個數字表明的意義. 納尼?
推薦:
if ([self canDeleteJob:job]) { ... } - (BOOL)canDeleteJob:(Job *)job { BOOL invalidJobState = job.JobState == JobState.New || job.JobState == JobState.Submitted || job.JobState == JobState.Expired; BOOL invalidJob = job.JobTitle && job.JobTitle.length; return invalidJobState || invalidJob; }
不推薦:
if (job.JobState == JobState.New || job.JobState == JobState.Submitted || job.JobState == JobState.Expired || (job.JobTitle && job.JobTitle.length)) { //.... }
清晰明瞭, 每一個函數DO ONE THING!
推薦:
- (void) someMethod { if (![someOther boolValue]) { return; } //Do something important }
不推薦:
- (void) someMethod { if ([someOther boolValue]) { //Do something important } }
一旦發現某個條件不符合, 當即返回, 條理更清晰。
全部的邏輯塊必須使用花括號包圍,即便條件體只需編寫一行代碼也必須使用花括號
推薦:
if (!error) { return success; }
不推薦:
if (!error) return success; ... if (!error) return success;
推薦:
- (void)registerUser(User *user) { // to do... }
不推薦:
- (void)registerUserName:(NSString *)userName password:(NSString *)password email:(NSString *)email { // to do... }
當發現實現某一功能須要傳遞的參數太多時, 就預示着你應該聚合成一個model類了...這樣代碼更整潔, 也不容易由於參數太多致使出錯。
屬性和冪等方法(屢次調用和一次調用返回的結果相同)使用點標記語法訪問,其餘的狀況使用方括號標記語法。
推薦:
view.backgroundColor = [UIColor orangeColor]; [UIApplication sharedApplication].delegate;
不推薦:
[view setBackgroundColor:[UIColor orangeColor]]; UIApplication.sharedApplication.delegate;
枚舉使用Objective-C方式來定義,枚舉命名是 類前綴+枚舉名,枚舉值要加枚舉名。
舉例:
typedef NS_ENUM(NSUInteger, HGMachineState) {
HGMachineStateNone,
HGMachineStateIdle,
HGMachineStateRunning,
HGMachineStatePaused
};
常量應該類名稱+「駱峯式」單詞大寫。
推薦:
static const NSTimeInterval HGSignInViewControllerFadeOutAnimationDuration = 0.4;
不推薦:
static const NSTimeInterval fadeOutTime = 0.4;
常數是優於串聯字符串或數字的,容許多個地方使用經常使用變量,能夠迅速改變不須要查找和替換。常量應該聲明爲靜態常量而不使用宏定義,除非明確須要定義一個宏。
推薦:
static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification"; static const CGFloat ZOCImageThumbnailHeight = 50.0f;
不推薦:
#define CompanyName @"Apple Inc." #define magicNumber 42
使用GCD代替使用sharedInstance,每次調用+ (id)sharedInstance函數都會付出取鎖的代價。
推薦:
+ (instancetype)sharedInstance { static id sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; }
不推薦:
+ (instancetype)sharedInstance { static id sharedInstance; @synchronized(self) { if (sharedInstance == nil) { sharedInstance = [[MyClass alloc] init]; } } return sharedInstance; }
定義一個協議是 類名+Delegate,並要使用weak 弱指針,協議使用可選@optional
@class ZOCSignUpViewController; @protocol ZOCSignUpViewControllerDelegate <NSObject> @required - (void)signUpViewController:(ZOCSignUpViewController *)controller didProvideSignUpInfo:(NSDictionary *); @optional - (void)signUpViewControllerDidPressSignUpButton:(ZOCSignUpViewController *)controller; @end @interface ZOCSignUpViewController : UIViewController @property (nonatomic, weak) id<ZOCSignUpViewControllerDelegate> delegate; @end
在發送委託代理方法以前,必定要先檢查該委託方法已經被實現(不然會崩潰)。
if ([self.delegate respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) { [self.delegate signUpViewControllerDidPressSignUpButton:self]; }
推薦
[UIView animateWithDuration:1.0 animations:^{ // something } completion:^(BOOL finished) { // something }];
不推薦
[UIView animateWithDuration:1.0 animations:^{ // something } completion:^(BOOL finished) { // something }];
使用「#pargma mark - 」實現方法的分組。建議按下面幾點單獨分組:
1.功能分組
2.代理協議實現分組
3.重寫父類方法
- (void)dealloc { /* ... */ } - (instancetype)init { /* ... */ } #pragma mark - View Lifecycle - (void)viewDidLoad { /* ... */ } - (void)viewWillAppear:(BOOL)animated { /* ... */ } - (void)didReceiveMemoryWarning { /* ... */ } #pragma mark - Custom Accessors - (void)setCustomProperty:(id)value { /* ... */ } - (id)customProperty { /* ... */ } #pragma mark - IBActions - (IBAction)submitData:(id)sender { /* ... */ } #pragma mark - Public - (void)publicMethod { /* ... */ } #pragma mark - Private - (void)zoc_privateMethod { /* ... */ } #pragma mark - UITableViewDataSource - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ } #pragma mark - ZOCSuperclass // ... overridden methods from ZOCSuperclass #pragma mark - NSObject - (NSString *)description { /* ... */ }
@interface TestClass : NSObject #pragma mark - Abstract Method //抽象方法 -(void)doWork; @end
抽象類不容許被實例化,因此須要在init方法中添加判斷代碼
@implementation TestClass - (id)init { if( [self class] == [TestClass class]) { @throw [NSException exceptionWithName:@"抽象類沒法實例化" reason:@"抽象類沒法實例化: TestClass" userInfo:nil]; } else { self = [super init]; if(self){ } return self; } } #pragma mark - Abstract Method - (void)doWork { @throw [NSException exceptionWithName:@"抽象方法沒有被實現" reason:@"抽象方法沒有被實現: doWork" userInfo:nil]; } @end
參數連接:
https://github.com/objc-zen/objc-zen-book