Objective-C編程規(guī)范

引言

一直以來都是在談如何開發(fā), 如開發(fā)的小技巧小經(jīng)驗

今天為什么突然說起編程規(guī)范來了呢?

因為在我看來, 編程規(guī)范是反映一個開發(fā)者或是一個開發(fā)團(tuán)隊素質(zhì)和成熟度的最重要標(biāo)志!

注意這里的措辭很嚴(yán)厲哈, 我用了"最重要"

當(dāng)我們看到各種文不表意的函數(shù)命名、剪不斷理還亂的文件和代碼結(jié)構(gòu)绑青、以及不符合Apple官方基本規(guī)范的風(fēng)格時

我想說: 程序員的加班 -- 你懂得(開發(fā)者制造的問題往往比他們解決的問題要多)

如果讀者覺得有比編程規(guī)范更重要的事情, 可以來辯, 歡迎拍磚~

本文的代碼規(guī)范基于The official raywenderlich.com Objective-C style guide, 但不局限于此, 結(jié)合實際開發(fā)遇到的問題, 做了部分修訂和補(bǔ)充

背景

Apple官方的代碼規(guī)范, 供補(bǔ)充參考:

目錄

語言

使用美式英語

Preferred:

UIColor *myColor = [UIColor whiteColor];

Not Preferred:

UIColor *myColour = [UIColor whiteColor];

代碼組織

使用#pragma mark -對function/protocol/delegate進(jìn)行分組

#pragma mark - Lifecycle

- (instancetype)init {}
- (void)dealloc {}
- (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)privateMethod {}

#pragma mark - Protocol

#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate

#pragma mark - NSCopying

- (id)copyWithZone:(NSZone *)zone {}

#pragma mark - NSObject

- (NSString *)description {}

空格

條件表達(dá)式的括號 (如: if/else/switch/while), 左括號和表達(dá)式在同一行, 右括號另起一行

Preferred:

if (user.isHappy) {
  // Do something
} else {
  // Do something else
}

Not Preferred:

if (user.isHappy)
{
  // Do something
}
else {
  // Do something else
}

避免使用冒號對齊方式, 除非代碼過長需要換行, 但是不要讓block也同樣保持冒號對齊

Preferred:

// blocks are easily readable
[UIView animateWithDuration:1.0f animations:^{
  // something
} completion:^(BOOL finished) {
  // something
}];

Not Preferred:

// colon-aligning makes the block indentation hard to read
[UIView animateWithDuration:1.0
                 animations:^{
                     // something
                 }
                 completion:^(BOOL finished) {
                     // something
                 }];
  • 簽代理

Preferred:

@interface UIViewController : UIResponder <NSCoding, UIAppearanceContainer>
@property (nonatomic, assign) id<ChooseProvinceViewControllerdDelegate> delegate;

Not Preferred:

@interface UIViewController : UIResponder<NSCoding,UIAppearanceContainer>
@property (nonatomic, assign) id <ChooseProvinceViewControllerdDelegate> delegate;

注釋

  • 確實需要, 才加注釋

  • 注釋是用來解釋why, 而不是what

Preferred:

// alignment attributes must have a secondViewAttribute
// therefore we assume that is refering to superview
// eg make.left.equalTo(@10)
if (!self.firstViewAttribute.isSizeAttribute && !self.secondViewAttribute) {
    secondLayoutItem = self.firstViewAttribute.view.superview;
    secondLayoutAttribute = firstLayoutAttribute;
}

Not Preferred:

/**
 * show head image
 */
@property (nonatomic, strong) DDImageView *headView;

// im conversation done edit
- (void)imConversationDoneEdit;
  • 添加的注釋要保持更新或刪除

命名

  • 使用長且描述性強(qiáng)的命名方式

Preferred:

UIButton *settingsButton;

Not Preferred:

UIButton *setBut;
  • 在類名和常量名前加上3個字母的前綴(Core Data entity names去掉前綴)

需要統(tǒng)一整個工程的命名前綴, 因為OC里沒有namespace, 工程越龐大后果越嚴(yán)重

  • 常量的命名采用"駝峰"的命名方式

Preferred:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3f;

Not Preferred:

static NSTimeInterval const fadetime = 1.7f;

成員的命名采用首字母小寫的"駝峰"命名方式, 并且使用auto-synthesis方式聲明成員, 而不是@synthesize方式

Preferred:

@property (nonatomic, copy) NSString *descriptiveVariableName;

Not Preferred:

id varnm;

命名時注意存儲數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)發(fā)生改變的時候岛宦,會不會引起命名的改變。

Preferred:

@property (nonatomic, strong) NSArray *actionSheetItems;
@property(nullable, nonatomic, copy) NSArray<UIBarButtonItem *> *items;   

Not Preferred:

@property (nonatomic, strong) NSArray *actionSheetItemArray;

圖標(biāo)資源命名

模塊名+功能名+[狀態(tài)],( [ ] : 表明可選)

圖標(biāo)在Xcode里面的名稱需要與圖標(biāo)的物理命名保持一致

Preferred:

addressbook_isvnetwork // 指代沒有狀態(tài)的圖標(biāo)名

addressbook_call_normal 
addressbook_call_highlight  // 指代有多種狀態(tài)的圖標(biāo)名

conference_member_delete_normal
conference_member_delete_highlight  // 指代功能名較長且有多種狀態(tài)的圖標(biāo)名

下劃線

使用self.方式來訪問對象的成員(參考點語法), 從視覺上就可以區(qū)分出哪些是本對象成員

注意:

  • 在初始化方法(init, initWithCoder:等), dealloc以及setters/getters方法中中必須使用保留的_variableName

  • 局部變量不要用下劃線開頭! 因為下劃線開頭的命名方式是Apple保留的命名方式

方法

  • 方法類型(-/+)的后面有個空格

  • 每一個參數(shù)都要有描述

注意:

  • 不要在多個參數(shù)的描述中添加"and", 例如下面的initWithWidth:height:方法

Preferred:

- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

Not Preferred:

-(void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height;  // Never do this.

變量

變量命名要可讀性強(qiáng), 避免用單個單詞的命名方式, 除了在for()循環(huán)里

指針的星號和變量名連在一起, 例如: NSString *text, 而不是NSString* text, NSString * text

避免直接使用_viriableName方式訪問對象的成員, 除了在初始化方法(init, initWithCoder:等), dealloc方法以及setters/getters方法中點語法

了解更多關(guān)于在初始化和dealloc中使用accessor方法, 請參考這里.

Preferred:

@interface RWTTutorial : NSObject

@property (nonatomic, copy) NSString *tutorialName;
@property (nonatomic, copy) NSArray<UIBarButtonItem *> *items;

@end 

Not Preferred:

@interface RWTTutorial : NSObject {
  NSString *tutorialName;
}

如果變量是一個度量的話(如按時間長度或者字節(jié)數(shù))子寓,那么最好把名字帶上它的單位

Preferred:

NSString *durationOfSeconds;

Not Preferred:

NSString *duration;

屬性

屬性要按照先atomicity后storage的順序, 這是為了和Apple的Interface Builder生成的代碼保持一致.不用對齊,根據(jù)功能用空格實現(xiàn)分組

Preferred:

@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nullable, readonly, nonatomic, copy) NSString *tutorialName;

Not Preferred:

@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (nonatomic) NSString *tutorialName;

注意:

  • 控件的storage屬性通常設(shè)置為weak, 而非strong

如果成員引用的對象是可變對象, 那么需要使用copy而非strong

Why?

因為即使成員的類型是NSString, 但實際傳入的如果是NSMutableString的對象

該對象在你不知情的情況下, 仍然會被修改

Preferred:

@property (nonatomic, copy) NSString *tutorialName;

Not Preferred:

@property (nonatomic, strong) NSString *tutorialName;

點語法

點語法實際是對accessor方法的封裝

了解更多點語法, 請參考這里

訪問和操作對象成員, 推薦使用點語法; Bracket notation is preferred in all other instances.

Preferred:

NSInteger arrayCount = [self.array count];
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;

Not Preferred:

NSInteger arrayCount = self.array.count;
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;

Object Literals

使用Object Literals(@)方式來快速創(chuàng)建NSString, NSDictionary, NSArray, NSNumber實例

注意:

  • 如果傳給NSArray, NSDictionary的值是nil會導(dǎo)致crash

Preferred:

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @10018;

Not Preferred:

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 *buildingStreetNumber = [NSNumber numberWithInteger:10018];
  • 容器類型最好標(biāo)明存儲數(shù)據(jù)的類型

Preferred:

@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows;

- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView ;
  • 在數(shù)組和字典中, 使用索引和關(guān)鍵字來獲取數(shù)據(jù)

Preferred:

NSString *name = names[1];
NSString *product = [productManagers valueForKey:@"kate"]

Not Preferred:

NSString *name = [names objectAtIndex:1];
NSString *product = [productManagers objectForKey:@"@kate"]

常量

使用static而非#define來聲明常量; unless explicitly being used as a macro

用const修飾時,const右邊的總是不能被修改.聲明時不用對齊,根據(jù)功能用空格實現(xiàn)分組

Preferred:

static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com";

static CGFloat const RWTImageThumbnailHeight = 50.0f;

Not Preferred:

#define CompanyName @"RayWenderlich.com"

#define thumbnailHeight 2.0f
  • 宏定義

使用大寫字母食零,用_分割單詞,宏定義中如果包含表達(dá)式或變量蝗肪,表達(dá)式和變量必須用小括號括起來

不到萬不得已不推薦使用宏定義像數(shù)字常量袜爪,通知的參數(shù)一般不推薦使用宏定義,推薦使用static const 的形式

Preferred:

#define SCREEN_RECT ([UIScreen mainScreen].bounds)

#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
  • 浮點數(shù)

使用浮點數(shù)在數(shù)值的后面加上f,用來區(qū)別double類型

Preferred:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3f;

Not Preferred:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;

枚舉

使用NS_ENUM()聲明枚舉, 因為它具有更強(qiáng)的類型檢查機(jī)制

For Example:

typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {
  RWTLeftMenuTopItemMain,
  RWTLeftMenuTopItemShows,
  RWTLeftMenuTopItemSchedule
};

當(dāng)然你還是可以顯式地設(shè)置枚舉的值

typedef NS_ENUM(NSInteger, RWTGlobalConstants) {
  RWTPinSizeMin = 1,
  RWTPinSizeMax = 5,
  RWTPinCountMin = 100,
  RWTPinCountMax = 500,
};

不要使用老式的枚舉定義方式, 除非編寫CoreFoundation C的代碼

Not Preferred:

enum GlobalConstants {
  kMaxPinSize = 5,
  kMaxPinCount = 500,
};

Case表達(dá)式

Case表達(dá)式通常不需要加括號

Case內(nèi)容有if判斷句, for循環(huán)和局部變量時, 需要加上括號 (左括號的右邊, break放在括號外). break與下一個case之間有空行.

switch (condition) {
  case 1:  {
     for () {
        // ...
     }
  }
     break;
  
  case 2: {
    if {
    //
    }
  }
    break;
  
  case 3:
    // ...
    break;
  
  default: 
    // ...
     break;
  }

多個Case表達(dá)式執(zhí)行相同的邏輯, 使用fall-through方式(即刪除表達(dá)式里的break)

此時, 需要加上注釋說明注釋

switch (condition) {
  case 1:
    // ** fall-through! **
  case 2:
    // code executed for values 1 and 2
    break;
    
  default: 
    // ...
    break;
}

私有成員

私有屬性要在類的實現(xiàn)中聲明: 放在class extension(即匿名category)中

For Example:

@interface RWTDetailViewController ()

@property (nonatomic, strong) GADBannerView *googleAdView;
@property (nonatomic, strong) ADBannerView *iAdView;
@property (nonatomic, strong) UIWebView *adXWebView;

@end

布爾

Objective-C使用YESNO, 而truefalse只用在CoreFoundation, C或C++代碼里

Since nil resolves to NO it is unnecessary to compare it in conditions. Never compare something directly to YES, because YES is defined to 1 and a BOOL can be up to 8 bits.

This allows for more consistency across files and greater visual clarity.

Preferred:

if (someObject) {}
if (![anotherObject boolValue]) {}

Not Preferred:

if (someObject == nil) {}
if ([anotherObject boolValue] == NO) {}
if (isAwesome == YES) {} // Never do this
if (isAwesome == true) {} // Never do this

如果BOOL類型的屬性是一個形容詞, 那么可以去掉"is"前綴, 但get accessor中仍然需要保留前綴

@property (assign, getter=editable) BOOL editable;

例子來自Cocoa Naming Guidelines.

條件語句

條件語句要加上括號, 即使是一行語句, 否則會存在隱患: even more dangerous defect

Preferred:

if (!error) {
  return success;
}

Not Preferred:

if (!error)
  return success;

or

if (!error) return success;

三元運算符

如果可以使代碼變得簡潔和高效, 那么可以考慮使用三元運算符?:, 否則還是用if表達(dá)式

通常, 給變量賦值時, 可以考慮使用三元運算符?:

Preferred:

NSInteger value = 5;
result = (value != 0) ? x : y;

BOOL isHorizontal = YES;
result = isHorizontal ? x : y;

Not Preferred:

result = a > b ? x = c > d ? c : d : y;

初始化方法

初始化方法要和Apple模板保持一致

- (instancetype)init {
  self = [super init];
  if (self) {
    // Do something
  }
  return self;
}

返回值類型是'instancetype'而不是'id'

關(guān)于instancetype, 請參考類構(gòu)造方法

類構(gòu)造方法

類構(gòu)造方法返回值類型是'instancetype'而不是'id', 這樣可以幫忙編譯器推導(dǎo)出返回值得類型

@interface Airplane
+ (instancetype)airplaneWithType:(RWTAirplaneType)type;
@end

了解更多關(guān)于instancetype: NSHipster.com.

CGRect函數(shù)

要獲取CGRectx, y, width, height, 不要直接訪問結(jié)構(gòu)體的成員, 而應(yīng)該使用CGGeometry functions

Apple官方對于CGGeometry的解釋:

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.

Preferred:

CGRect frame = self.view.frame;

CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0f, 0.0f, width, height);

Not Preferred:

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;
CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size };

Golden Path

如果把需要執(zhí)行的邏輯比作"golden"或"happy" path

那么在判斷條件不滿足時, 直接return退出方法, 而不是判斷條件滿足時, 執(zhí)行該Golden Path

Preferred:

- (void)someMethod {
  if (![someOther boolValue]) {
    return;
  }
  // Do something important
}

Not Preferred:

- (void)someMethod {
  if ([someOther boolValue]) {
    // Do something important
  }
}

錯誤處理

通過方法的返回值而不是返回的error引用, 來做錯誤處理的判斷條件

Preferred:

NSError *error;
if (![self trySomethingWithError:&error]) {
  // Handle Error
}

Not Preferred:

NSError *error;
[self trySomethingWithError:&error];
if (error) {
  // Handle Error
}

單例

單例對象的實例化必須要確保線程安全

+ (instancetype)sharedInstance {
  static id sharedInstance = nil;

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[self alloc] init];
  });

  return sharedInstance;
}

否則可能會出現(xiàn)這樣的問題possible and sometimes prolific crashes.

換行

頭文件中的方法, 使用冒號對齊的方式

Preferred:

 - (void)setViewWithHeadImageUrl:(NSString *)headImageUrl 
                            name:(NSString *)name 
                     phoneNumber:(NSString *)phoneNumber;

Not Preferred:

- (void)setViewWithHeadImageUrl:(NSString *)headImageUrl name:(NSString *)name phoneNumber:(NSString *)phoneNumber;

實現(xiàn)文件或方法調(diào)用時, 不用冒號對齊

Preferred:

[[MSDBHelper sharedInstance] updateCallRecordsWithNumber:number isPersonalContact:YES oldName:oldContact.displayName toNewName:@""];

Not Preferred:

[[MSDBHelper sharedInstance] updateCallRecordsWithNumber:number
                                       isPersonalContact:YES
                                                 oldName:oldContact.displayName
                                               toNewName:@""];

如果語句過長, 需要考慮代碼的分解和優(yōu)化

Preferred:

NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[ctpManager connectToHost:kHostNameCloudPhoneNoport onPort:kCTPPort userInfo:userInfo;
[userInfo setObject:[AccountLoginModel sharedInstance].userInfo.mobilephone forKey:CTP_AUTHUSER_USER_NAME, nil];
    

Not Preferred:

 [ctpManager connectToHost:kHostNameCloudPhoneNoport onPort:kCTPPort userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[AccountLoginModel sharedInstance].userInfo.mobilephone, CTP_AUTHUSER_USER_NAME, nil];

頭文件

  • 自定義頭文件放在系統(tǒng)頭文件的前面

  • 按功能分開薛闪,加空格以示區(qū)分

  • 按字母表排序

Preferred:

#import "DailModel"

#import "DialView.h"

#import "DialViewController.h"

#import <QYCTPManager/CTPManager.h>

Not Preferred:

#import <QYCTPManager/CTPManager.h>
#import "DialView.h"
#import "DailModel"
#import "DialViewController.h"
  • 不要引入無關(guān)的頭文件

  • 盡量使用向前聲明取代引入辛馆,這樣不僅可以縮減編譯時間,而且還能降低彼此依賴程度

版權(quán)聲明

Preferred:

//  MSDetailRecordsViewController.m
//  CloudPhone
//
//  Created by chenguang (guochenguang@qiyoukeji.com) on 15-12-6.
//  Copyright (c) 2015年 QIYOU Ltd. All rights reserved.
//

Not Preferred:

//  MSDetailRecordsViewController.m
//  chenguang
//
//  Created by chenguang on 15-12-6.
//  Copyright (c) 2015年 CloudPhone. All rights reserved.
//

Xcode Project

  • Xcode Group要和文件系統(tǒng)里的文件夾關(guān)聯(lián)起來

  • 代碼不僅要按照類型分組, 也要按照功能和特性進(jìn)行分組

  • 如果可以的話, 打開Build Settings里的"Treat Warnings as Errors"選項

  • 并且盡可能多的打開additional warnings

如果需要忽略特定的warning, 請參考Clang's pragma feature.

其他Objective-C編程規(guī)范

更多文章, 請支持我的個人博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逛绵,一起剝皮案震驚了整個濱河市怀各,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌术浪,老刑警劉巖瓢对,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異胰苏,居然都是意外死亡硕蛹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門硕并,熙熙樓的掌柜王于貴愁眉苦臉地迎上來法焰,“玉大人,你說我怎么就攤上這事倔毙“R牵” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵陕赃,是天一觀的道長卵蛉。 經(jīng)常有香客問我,道長么库,這世上最難降的妖魔是什么傻丝? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮诉儒,結(jié)果婚禮上葡缰,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好泛释,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布滤愕。 她就那樣靜靜地躺著,像睡著了一般胁澳。 火紅的嫁衣襯著肌膚如雪该互。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天韭畸,我揣著相機(jī)與錄音宇智,去河邊找鬼。 笑死胰丁,一個胖子當(dāng)著我的面吹牛随橘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锦庸,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼机蔗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了甘萧?” 一聲冷哼從身側(cè)響起萝嘁,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扬卷,沒想到半個月后牙言,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡怪得,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年咱枉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徒恋。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚕断,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出入挣,到底是詐尸還是另有隱情亿乳,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布径筏,位于F島的核電站风皿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏匠璧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一咸这、第九天 我趴在偏房一處隱蔽的房頂上張望夷恍。 院中可真熱鬧,春花似錦、人聲如沸酿雪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽指黎。三九已至朋凉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間醋安,已是汗流浹背杂彭。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留吓揪,地道東北人亲怠。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像柠辞,于是被迫代替她去往敵國和親团秽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 命名規(guī)范 1.【強(qiáng)制】 代碼中的命名均不能以下劃線或美元符號開始叭首,也不能以下劃線或美元符號結(jié)束习勤。 反例: _nam...
    666真666閱讀 778評論 2 4
  • 本文記錄一下Objective-C編程規(guī)范以及一些建議,可能后續(xù)會有些修改和補(bǔ)充焙格,至于初衷是最近接手的項目中代碼"...
    SuperMario_Nil閱讀 1,805評論 2 13
  • 方法聲明和定義 -或者+和返回類型之間須使用一個空格图毕,括號要同行并有一個空格 方法應(yīng)該像這樣: 如果函數(shù)名字太長,...
    Dayon閱讀 235評論 0 1
  • 從其他地方整理了一些編碼規(guī)范的資料间螟,分享給大家吴旋。YoY 1.語言(Language) 需要使用US English...
    大臉貓121閱讀 440評論 0 2
  • Introduction 這個style guide規(guī)范描述了我們iOS開發(fā)團(tuán)隊喜歡的Objectiv-C編程習(xí)慣...
    小山Sam閱讀 657評論 0 4