命名規范
原則: 防止命名沖突、可讀性高
方式: 駝峰式命名法
說明: 每個模塊都需要加上前綴
一、常量命名
1.1 在常量前邊加上字母k作為標記
static const NSTimeInterval kAnimationDuration = 0.3
1.2 定義作為NSDictionary或者NSNotification的key值字符串時加上const關鍵字
NSString *const UIApplicationDidEnterBackgroundNotification
1.3 若常量作用域超出.m文件,需要在類外可見時,使用extern關鍵字,并加上類名前綴
extern NSString *const PGThumbnailSize
1.4 全局常量包括 通知 或者 關鍵字 都盡可能使用const定義
Tips
- 使用宏定義可能導致宏被 重定義,引用不同的文件可能導致 宏不同
- #define 也需要添加k前綴
二、枚舉命名
2.1 枚舉類型 命名要加相關類名前綴并且 枚舉值命名 要加枚舉類型前綴,示例如下
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
UIViewAnimationTransitionNone,
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
UIViewAnimationTransitionCurlUp,
UIViewAnimationTransitionCurlDown,
};
typedef NS_OPTIONS(NSUInteger, UIControlState) {
UIControlStateNormal = 0,
UIControlStateHighlighted = 1 << 0,
UIControlStateDisabled = 1 << 1,
};
優點:增強類型檢查,更好的代碼可讀性
三、 變量和對象的命名
方式: 修飾+類型
@property (nonatomic, strong) UILabel *titleLabel; //表示*標題*的label,是*UILabel*類型
@property (nonatomic, strong) UIButton *confirmButton; //表示*確認*的button,是*UIButton*類型
對于BOOL類型,需要加is前綴
- (BOOL)isEqualToString:(NSString *)aString;
- (BOOL)hasPrefix:(NSString *)aString;
四、 方法命名
4.1 添加 參數 提示
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender;
4.2 回調方法 和 通知方法 的命名
原則: 動作發生之前用Will,發生之后用Did,詢問是否發生用Should
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath; //將要選擇這一行cell
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; //已經選擇這一行cell
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); //是否高亮(選擇這一行cell)
4.3 回調方法第一個參數是調用者
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (void)buttonTapped:(UIButton*)sender;
4.4 方法符合語法
大部分方法可以分為兩類:要什么 和 做什么
-
要什么
表示取得某個對象,要以名詞作為方法的開頭
- (UIImage *)imageNamed:(NSString *)name;
-
做什么
表示執行某種操作,要以動詞作為方法開頭
- (void)setUpNavBar
書寫規范
一、 ViewController 書寫規范
1.1 方法書寫順序(依次)
* 生命周期
* 基類public方法
* 代理方法
* 本類private方法
* 通知方法
* 請求方法
二、*代碼目錄分類* 規范
2.1 總代碼目錄架構

2.2 Managers 目錄

2.3 Models 目錄

2.4 Controllers 目錄

2.5 General 目錄

2.6 Macros 目錄

2.7 Vendors 目錄

2.8 Assets.xcassets 目錄

三、 寫碼規范
3.1 判斷**nil**或者**YES/NO**
```javascript
if (obj)
{
//...
}
if (!obj)
{
//...
}
3.2 NSArray NSDictionary 初始化方法
NSArray *contacters = @[@"Allen", @"Bob", @"Chirs"];
NSDictionary *bookInfo = @{@"BookName":@"iOS開發之進階篇", @"BookPrice":@"999999.0RMB", @"BookAuthor":@"RenSihao"};
NSNumber *isHide = @NO;
NSNumber *errorCode = @404;
優點:簡潔明了,同時防止初始化進去一個nil
3.3 定義屬性盡可能寫全參數
@property (nonatomic, readwrite, copy) NSString *name;
- 如果是內部使用的屬性, 需定義成該類的私有屬性(寫在.m文件的class extension里)
- 對于擁有Mutable子類型的對象, 例如NSString NSArray NSDictionary NSDictionary, 一定要定義成copy屬性
- 盡量不要暴露mutable類型的對象在public interface, 建議在.h定義一個Inmutable類型的屬性, 然后在.m的get函數里面返回一個內部定義的mutable變量
- 不要出現混合聲明,盡可能都使用@property聲明
3.4 BOOL類型賦值
BOOL isAdult = age > 18;
3.5 拒絕死值
if (country = Countries.China)
{ //... }
const int adultAge = 18;
if (age > adultAge)
{ //... }
3.6 復雜的條件判斷
如果判斷較為復雜,盡可能寫到一個方法里
if ([self canDeleteAccount:account])
{ //... }
/**
method
*/
- (BOOL)canDeleteAccount:(account)
{
if (account.balance == 0 || account.owner.isDead == YES || account.isCancel == YES)
{
return YES;
}
else
{
return NO;
}
}
3.7 嵌套判斷
if (!user.account) return NO;
if (!user.password) return NO;
return YES;
3.8 使用Block避免循環引用
- block內部使用外部聲明的強引用去訪問對象A,則block內部會產生一個強引用指向對象A
- block內部使用外部聲明的弱引用去訪問對象A,則block內部會產生一個弱引用指向對象A
__weak typeof(self) weakSelf = self;
obj.block = ^ {
__strong typeof(self) strongSelf = self;
if (strongSelf)
{
[strongSelf doSomething]; //strongSelf != nil
}
else
{
//maybe nothing...
return ;
}
}
3.9 宏的格式
宏要寫成大寫,至少一個字母大寫,全部小寫有時候Xcode不會自動提示
3.10 加載xib
加載xib名稱使用 NSStringFromClass()
[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([UserListCell class]) bundle:nil] forCellReuseIdentifier:ID];
3.11 繼承
子類繼承父類方法,需要重寫一定要先調用父類進行初始化操作
建議在父類方法后追加 NS_REQUIRES_SUPER ,作用是子類重寫這個方法就會自動警告提示要調用這個super方法
- (void)addAllNotifications;
3.12 命名控件避開系統命名
例如
@property (nonatomic, strong) UILabel *textLabel; //錯誤命名
@property (nonatomic, strong) UILabel *contentLabel; //正確命名
3.13 id類型
id類型屬性調用不能用點語法, 調用get方法只能用中括號
[id 方法名]
3.14 判斷if書寫方式
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) return 40;
if (indexPath.row == 1) return 50;
if (indexPath.row == 2) return 60;
return 44;
}
3.15 快速調試
需要注釋掉一個方法,在該方法內部第一行return即可,無需大段注釋
3.16 監聽鍵盤通知
使用
UIKIT_EXTERN NSString *const UIKeyboardWillChangeFrameNotification
優點:無論鍵盤切換輸入法,切換表情等原因導致frame更改,該通知一定會監聽得到
3.17 通知命名
使用const修飾,以Notification結尾
3.18 BOOL類型屬性
如果是聲明BOOL類型,建議在括號中重寫get方法
@property (nonatomic, readonly, getter = isKeyWindow) BOOL keyWindow;
3.19 自定義方法
不能使用and這個單詞連接參數
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
3.20 點語法
盡可能使用點語法訪問屬性,但是訪問其他實例對象使用括號
view.backgroundColor = [UIColor redColor];
[UIApplication sharedApplication].delegate; //推薦
[view setBackgroundColor:[UIColor redColor]];
UIApplication.sharedApplication.delegate; //不推薦
3.21 引用頭文件
類的頭文件(.m文件)盡量不要引用其他頭文件,無需知道類的內部細節使用@class即可