一篇oc編碼風(fēng)格的文章,有什么不對(duì)的地方請(qǐng)指出
引見(jiàn)
下面是來(lái)自蘋果的一些有關(guān)編碼風(fēng)格指導(dǎo)的文件。如果在本文沒(méi)有提到的內(nèi)容,在這些文件中可能可以查到:
- The Objective-C Programming Language
- Cocoa Fundamentals Guide
- Coding Guidelines for Cocoa
- iOS App Programming Guide
點(diǎn)語(yǔ)法
建議用點(diǎn)語(yǔ)法表示,并設(shè)置屬性
For example:
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
Not:
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
空格
流程控制(if/else/switch/while),新的分支應(yīng)該從新的一行開(kāi)始
For example:
if (user.isHappy) {
// Do something
}
else {
// Do something else
}
For example:
if (!error) {
return success;
}
Not:
if (!error)
return success;
or
if (!error) return success;
三元運(yùn)算符
三元運(yùn)算符的意圖是為了增加代碼的簡(jiǎn)潔,三元運(yùn)算符應(yīng)該僅用一個(gè)表達(dá)式來(lái)執(zhí)行一個(gè)條件判斷,多個(gè)條件更多的是用if語(yǔ)句來(lái)執(zhí)行。
For example:
result = a > b ? x : y;
Not:
result = a > b ? x = c > d ? c : d : y;
方法
定義一個(gè)方法,應(yīng)該在- or +后面加一個(gè)空格,多個(gè)參數(shù)應(yīng)該用空格分開(kāi)。
For example:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
變量命名
變量命名應(yīng)該具有描述性意義,一個(gè)變量的名字需要有正確的使用價(jià)值。
不推薦使用單一的字母變量名,除了循環(huán)中的計(jì)數(shù)器變量。
在任何可能的情況下,應(yīng)該使用屬性定義代替成員變量。
For example:
@interface NYTSection: NSObject
@property (nonatomic) NSString *headline;
@end
Not:
@interface NYTSection : NSObject {
NSString *headline;
}
變量修飾符
當(dāng)涉及到變量修飾符introduced with ARC,修飾符the qualifier (__strong, __weak, __unsafe_unretained, __autoreleasing)應(yīng)該寫在 * 和變量名之間,例如:NSString * __weak text。
一般命名
蘋果的命名規(guī)則在任何可能的地方都試用, 包括內(nèi)存管理規(guī)則 http://stackoverflow.com/a/2865194/340508.
盡量用長(zhǎng)的、描述性強(qiáng)的、有價(jià)值的名字總是好的。
For example:
UIButton *settingsButton;
Not
UIButton *setBut;
定義類名和常量的時(shí)候,需要添加3個(gè)字母的標(biāo)識(shí)符,不要用兩個(gè)字母。并遵循駝峰命名規(guī)則。兩個(gè)字母的前綴是蘋果所保留的命名reserved for use by Apple.
For example:
static const NSTimeInterval NYTArticleViewControllerNavigationFadeAnimationDuration = 0.3;
Not:
static const NSTimeInterval fadetime = 1.7;
屬性和局部變量必須以小寫字母開(kāi)頭
類別
類別為一個(gè)類提供功能的類,類別的命名應(yīng)該具有實(shí)際意義。
For example:
@interface UIViewController (NYTMediaPlaying)
@interface NSString (NSStringEncodingDetection)
Not:
@interface NYTAdvertisement (private)
@interface NSString (NYTAdditions)
注釋
代碼中添加相應(yīng)的注釋對(duì)代碼的維護(hù)有很大的幫助。不推薦成塊的注釋,因?yàn)榇a應(yīng)該盡可能的自我記錄,只需要間接性的,很少的注釋。
不可變對(duì)象
NSString, NSDictionary, NSArray, 和 NSNumber的創(chuàng)建應(yīng)該使用簡(jiǎn)單的方式。
For example:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
Not:
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018];
CGRect Functions
當(dāng)訪問(wèn)一個(gè)CGRect中的 x, y, width, or height這些成員時(shí),必須使用CGGeometry functions 來(lái)替代直接訪問(wèn)成員. 從蘋果的 CGGeometry 參考文檔來(lái)看:
All functions described in this reference that take CGRect data structures as inputs implicitly standardize those rectangles before calculating their results. For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.
For example:
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
Not:
CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
常量
常量盡量用static聲明,有時(shí)也可以用#define宏定義聲明。
For example:
static NSString * const NYTAboutViewControllerCompanyName = @"The New York Times Company";
static const CGFloat NYTImageThumbnailHeight = 50.0;
Not:
#define CompanyName @"The New York Times Company"
#define thumbnailHeight 2
枚舉類型
枚舉一般使用固定的格式創(chuàng)建,蘋果推薦使用NS_ENUM來(lái)創(chuàng)建。
Example:
typedef NS_ENUM(NSInteger, NYTAdRequestState) {
NYTAdRequestStateInactive,
NYTAdRequestStateLoading
};
位掩碼
當(dāng)使用bitmasks時(shí),必須使用NS_OPTIONS宏創(chuàng)建。
Example:
typedef NS_OPTIONS(NSUInteger, NYTAdCategory) {
NYTAdCategoryAutos = 1 << 0,
NYTAdCategoryJobs = 1 << 1,
NYTAdCategoryRealState = 1 << 2,
NYTAdCategoryTechnology = 1 << 3
};
私有屬性
私有屬性應(yīng)該在類的實(shí)現(xiàn)文件implementation中聲明,就是在類擴(kuò)展中聲明。
For example:
@interface NYTAdvertisement ()
@property (nonatomic, strong) GADBannerView *googleAdView;
@property (nonatomic, strong) ADBannerView *iAdView;
@property (nonatomic, strong) UIWebView *adXWebView;
@end
@implementation NYTAdvertisement
單例
單例對(duì)象應(yīng)該使用線程安全的方式來(lái)創(chuàng)建。
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[[self class] alloc] init];
});
return sharedInstance;
}
這將防止 可能意想不到的crashes.
Imports
在同時(shí)導(dǎo)入多個(gè)類的時(shí)候必須使用分組的方式來(lái)區(qū)分http://ashfurrow.com/blog/structuring-modern-objective-c.
框架導(dǎo)入使用@import。
// Frameworks
@import QuartzCore;
// Models
#import "NYTUser.h"
// Views
#import "NYTButton.h"
#import "NYTUserView.h"
協(xié)議
定義協(xié)議方法的第一個(gè)參數(shù)應(yīng)該是一個(gè)該類的對(duì)象,delegate or data source protocol。
這樣有助于消除同時(shí)被多個(gè)對(duì)象引用的協(xié)議所帶來(lái)的歧義。
For example:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
Not:
- (void)didSelectTableRowAtIndexPath:(NSIndexPath *)indexPath;