@inerface的11條規(guī)范寫法

總結(jié)一些interface聲明時(shí)的規(guī)范,相關(guān)宏的介紹仪媒,定義方法時(shí)有用的修飾符缤弦,編寫注釋的規(guī)范,最終寫出一個(gè)合格的頭文件形耗。

  • 1.讀寫權(quán)限
    • 1.1實(shí)例變量的@public,@protected,@private關(guān)鍵字
    • 1.2屬性的readonly,readwrite關(guān)鍵字
  • 2.前向聲明
  • 3.只暴露必要的接口和實(shí)現(xiàn)
    • 3.1不要暴露任何只在類內(nèi)部使用的私有方法
    • 3.2不要在頭文件里聲明類內(nèi)部遵循的protocol
  • 4.nullability說明
  • 5.定義枚舉
    • 5.1 NS_ENUM
    • 5.2 NS_OPTIONS
    • 5.3 字符串枚舉
  • 6.使用extern向外部提供只讀常量
  • 7.向子類和category提供父類的私有屬性
  • 8.標(biāo)明designated initializer
  • 9.API版本控制
    • 9.1 available
    • 9.2 unavailable
    • 9.3 deprecated
  • 10.額外的修飾符
    • 10.1泛型
    • 10.2 NS_REQUIRES_SUPER
    • 10.3 NS_NOESCAPE
  • 11.寫注釋
    • 11.1單行注釋
    • 11.2多行注釋
    • 11.3枚舉注釋
    • 11.4幾個(gè)注釋約定

1.讀寫權(quán)限

.h文件里的聲明是用于暴露給外部的接口哥桥,而類內(nèi)部的私有方法、私有屬性和實(shí)例變量激涤,應(yīng)該放到.m文件的interface extension里拟糕。

1.1 實(shí)例變量的@public,@protected,@private關(guān)鍵字

這3個(gè)關(guān)鍵字用于修飾實(shí)例變量,不能用于修飾屬性倦踢。當(dāng)錯(cuò)誤地使用了實(shí)例變量時(shí)送滞,Xcode會報(bào)錯(cuò)提示。

關(guān)鍵字 說明
@private 作用范圍只能在自身類
@protected 作用范圍在自身類和繼承自己的子類辱挥,什么都不寫犁嗅,默認(rèn)是此屬性。
@public 作用范圍最大晤碘,在任何地方褂微。

示例代碼:

//SearchManager.h
@interface SearchManager : NSObject {
    @public    NSInteger *state;
    @public    NSInteger *timeout;
    @protected id *searchAPI;
    @private   id _privateIvar;
}
@end

由于會暴露私有變量,并且沒有@property的一些高級關(guān)鍵字园爷,很少在頭文件里聲明實(shí)例變量宠蚂。優(yōu)先使用@property。

1.2 屬性的readonly,readwrite關(guān)鍵字

頭文件中的屬性是用于描述這個(gè)對象的一系列特性集合童社。
聲明@property時(shí)求厕,在.h里使用readonly,讓外部只有讀的權(quán)限,在.m里使用readwrite呀癣,使內(nèi)部擁有讀寫權(quán)限旅东。

示例代碼:

//SearchManager.h
@interface SearchManager : NSObject
@property (nonatomic, readonly) NSInteger * state;
@end
//SearchManager.m
@interface SearchManager : NSObject
@property (nonatomic, readwrite) NSInteger * state;
@end

2.前向聲明

當(dāng)在@interface的接口里用到了其他類,不要在.h里直接導(dǎo)入類的頭文件十艾,這樣會讓使用此頭文件的地方也導(dǎo)入這些不必要的其他頭文件。正確的做法是使用關(guān)鍵字@class進(jìn)行前向聲明腾节。當(dāng)然忘嫉,如果是繼承了父類,還是需要import父類的頭文件案腺。
示例代碼:

//SearchManager.h
#import "SearchManagerBase.h"http://導(dǎo)入父類的頭文件

@class LocationModel;//前向聲明LocationModel類

typedef void(^LocationSearchCompletionHandler)(LocationModel *location, NSError *error);
@interface LocationSearchManager : SearchManagerBase
- (void)searchLocationWithKeyword:(NSString *)keyword completionHandler:(LocationSearchCompletionHandler)completionHandler;
@end

使用@class會告訴編譯器有這么一個(gè)類存在庆冕,但是現(xiàn)在并不關(guān)心這個(gè)類的具體實(shí)現(xiàn),等到調(diào)用者在.m里使用的時(shí)候再import這個(gè)類即可劈榨。使用@class和@protocol分別聲明一個(gè)類和一個(gè)protocol访递。
使用前向引用的原因有兩個(gè):

  • 提升編譯效率。
    如果import了LocationModel.h同辣,那么當(dāng)LocationModel.h的內(nèi)容發(fā)生變化時(shí)拷姿,所有import了LocationModel.h的地方都需要重新編譯。如果.m引用了SearchManager.h旱函,但是并沒有使用LocationModel响巢,就會增加不必要的編譯,降低開發(fā)效率棒妨。
  • 解決交叉引用的問題踪古。
    如果類A的頭文件import了B,類B的頭文件import了A券腔,這樣在編譯時(shí)會報(bào)錯(cuò):“can not find interface declaration”伏穆,這是因?yàn)镺bjective-C不允許交叉引用。

3.只暴露必要的接口和實(shí)現(xiàn)

3.1不要暴露任何只在類內(nèi)部使用的私有方法

頭文件里只聲明那些給外部使用的公開方法纷纫,并且在設(shè)計(jì)時(shí)需要考慮到可測試性枕扫,遵循單一職責(zé)。
私有方法只定義在類內(nèi)部涛酗,并且為了進(jìn)行區(qū)別铡原,建議在私有方法前加上前綴,例如- (void)p_myPrivateMethod商叹。
由于Apple在它的編碼規(guī)范里聲明了燕刻,Apple公司擁有下劃線的方法前綴,就像它擁有NS,UI這些類名前綴一樣剖笙,因此不建議我們的私有方法直接使用下劃線作為前綴卵洗。否則,當(dāng)你在繼承Cocoa Touch的類時(shí),有可能會覆蓋父類的私有方法过蹂,造成難以調(diào)試的錯(cuò)誤十绑。

3.2不要在頭文件里聲明類內(nèi)部遵循的protocol

錯(cuò)誤的示例代碼:

//SearchManager.h
@interface SearchManager : NSObject<NSCoding, UITableViewDelegate>
@property (nonatomic, readonly) NSInteger * state;
@end

UITableViewDelegate是類內(nèi)部使用時(shí)遵循的protocol,沒有必要暴露給外部酷勺,因此應(yīng)該放到.m文件里本橙。
NSCoding則描述了類的特性,用于告訴外部本類可以使用歸檔脆诉,因此應(yīng)該放在頭文件里甚亭。

4.nullability說明

在聲明時(shí),可以使用下列關(guān)鍵字描述對象是否可以為nil击胜。

關(guān)鍵字 說明
nullable 可空亏狰,用于描述objc對象
nonnull 不可空,用于描述objc對象
null_unspecified 不確定偶摔,用于描述objc對象
null_resettable set可空暇唾,get不為空。僅用于property
_Nullable 可空辰斋,用于描述C指針和block
_Nonnull 不可空策州,用于描述C指針和block
_Null_unspecified 不確定,用于描述C指針和block

示例代碼:

//SearchManager.h
#import "SearchManagerBase.h"
@class LocationModel;

typedef void(^LocationSearchCompletionHandler)(LocationModel *_Nullable location, NSError *_Nullable error);
@interface LocationSearchManager : SearchManagerBase
- (void)searchLocationWithKeyword:(nonnull NSString *)keyword completionHandler:(LocationSearchCompletionHandler _Nonnull)completionHandler;
@end

如果向一個(gè)使用nonnull修飾的值賦空宫仗,編譯器會給出警告抽活。
在開發(fā)時(shí),大部分時(shí)候使用的都是nonnull锰什,因此Apple提供了一對宏NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END來進(jìn)行快速修飾下硕,寫在兩個(gè)宏之間的屬性、方法汁胆,均會使用nonnull修飾梭姓。
示例代碼:

//LocationSearchManager.h

#import "SearchManagerBase.h"
@class LocationModel;

NS_ASSUME_NONNULL_BEGIN
typedef void(^LocationSearchCompletionHandler)(LocationModel *_Nullable location, NSError *_Nullable error);
@interface LocationSearchManager : SearchManagerBase
- (void)searchLocationWithKeyword:(NSString *)keyword completionHandler:(LocationSearchCompletionHandler)completionHandler;
@end
NS_ASSUME_NONNULL_END

5.定義枚舉

關(guān)于NS_ENUM和NS_OPTIONS的區(qū)別,參考這里嫩码。
簡單來說誉尖,NS_OPTIONS提供了按位掩碼的功能。

5.1 NS_ENUM

示例代碼:

typedef NS_ENUM(NSInteger,SearchState) {
    SearchStateNotSearch,
    SearchStateSearching,
    SearchStateSearchFinished,
    SearchStateSearchFailed
};

5.2 NS_OPTIONS

示例代碼铸题,參考NSKeyValueObserving.h

typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {
    NSKeyValueObservingOptionNew,
    NSKeyValueObservingOptionOld,
    NSKeyValueObservingOptionInitial,
    NSKeyValueObservingOptionPrior
};

在使用時(shí)就可以用|組合多個(gè)option:

[_webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];

5.3 字符串枚舉

當(dāng)使用字典作為參數(shù)傳遞铡恕,或者作為返回值時(shí),往往難以直接提供字典的key丢间,現(xiàn)在使用字符串枚舉即可解決這個(gè)問題探熔。
示例代碼,參考NSKeyValueObserving.h

//使用NS_STRING_ENUM宏烘挫,定義了一個(gè)枚舉類型
typedef NSString * NSKeyValueChangeKey NS_STRING_ENUM;

FOUNDATION_EXPORT NSKeyValueChangeKey const NSKeyValueChangeKindKey;
FOUNDATION_EXPORT NSKeyValueChangeKey const NSKeyValueChangeNewKey;
FOUNDATION_EXPORT NSKeyValueChangeKey const NSKeyValueChangeOldKey;
FOUNDATION_EXPORT NSKeyValueChangeKey const NSKeyValueChangeIndexesKey;
FOUNDATION_EXPORT NSKeyValueChangeKey const NSKeyValueChangeNotificationIsPriorKey;

//使用泛型诀艰,聲明了change參數(shù)用到的key,是在NSKeyValueChangeKey的枚舉范圍中
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;

6.使用extern向外部提供只讀常量

這不關(guān)@interface的事,但是和頭文件有關(guān)其垄,就放在一起說明了苛蒲。

//SearchManager.h
extern NSString *const SearchErrorDomain;
extern NSInteger SearchDefaultTimeout;

@interface SearchManager : NSObject
@end
//SearchManager.m
NSString *const SearchErrorDomain = @"SearchErrorDomain";
const NSInteger SearchDefaultTimeout = 20;

@interface SearchManager()
@end

7.向子類和category提供父類的私有屬性

由于類的頭文件只存放那些暴露給外部的屬性和方法,在遇到這些情況時(shí)绿满,會遇到障礙:

  • 在子類里或者category里臂外,想要使用父類定義在.m里的私有屬性。
  • 在類的頭文件里屬性是readonly喇颁,但是在子類或者category里寄月,需要readwrite權(quán)限。
    由于這些屬性并沒有暴露在頭文件里无牵,因此需要另外建立一個(gè)私有頭文件,用來存放這些需要暴露給子類和category的屬性厂抖。
    可以參考Apple官方的UIGestureRecognizerSubclass.h茎毁。
    示例代碼:
//SearchManager.h
@interface SearchManager : NSObject
///外部訪問,只有讀權(quán)限
@property (nonatomic, readonly) SearchState state;
@end
//SearchManager.m
@interface SearchManager()
///內(nèi)部使用忱辅,有讀寫權(quán)限
@property (nonatomic, assign) SearchState state;
///只在內(nèi)部使用的私有屬性
@property (nonatomic, strong) id searchAPI;
@end
///暴露給子類和category的私有屬性和私有方法
//SearchManagerInternal.h
///限制使用此頭文件七蜘,防止被別的類誤用
#ifdef SEARCHMANAGER_PROTECTED_ACCESS

#import "SearchManager.h"
@interface SearchManager()
///在internal.h里,重新聲明為readwrite權(quán)限
@property (nonatomic, readwrite, assign) SearchState state;
///暴露私有屬性
@property (nonatomic, strong) id searchAPI;
///暴露私有方法
- (void)p_privateMethod;
@end

#else
#error Only be included by SearchManager's subclass or category!
#endif
///category的實(shí)現(xiàn)文件
//SearchManager+Category.m
///聲明私有頭文件的使用權(quán)限
#define SEARCHMANAGER_PROTECTED_ACCESS
///導(dǎo)入私有頭文件
#import "SearchManagerInternal.h"

@implementation SearchManager(Category)
- (void)categoryMethod {
    //擁有了讀寫權(quán)限
    self.state = SearchStateSearching;
    //可以訪問私有屬性
    [self.searchAPI startSearch];
    //可以使用私有方法
    [self p_privateMethod];
}
@end

SearchManagerInternal.h其實(shí)也是公開的墙懂,其他類也能夠?qū)氩⑹褂孟鹇保荒茉陂_發(fā)時(shí)進(jìn)行約定。如果想要限制其他類導(dǎo)入损搬,并且提示錯(cuò)誤碧库,Internal.h可以使用如下方式:

#ifdef MYCLASS_PROTECTED_ACCESS
//聲明部分
#else
#error Only be included by MYCLASS's subclass or category!
#endif

這樣在別的類內(nèi)意外地導(dǎo)入了Internal.h時(shí)就會產(chǎn)生編譯警告,并且無法直接使用巧勤。缺點(diǎn)是需要在所有使用到Internal.h的地方都#define MYCLASS_PROTECTED_ACCESS嵌灰。

8.標(biāo)明designated initializer

指定初始化方法,即接收參數(shù)最多的那個(gè)初始化方法颅悉,其他初始化方法調(diào)用它即可沽瞭,這樣設(shè)計(jì)的目的是為了保證所有初始化方法都正確地初始化實(shí)例變量。
在方法后面加上NS_DESIGNATED_INITIALIZER宏即可剩瓶。這樣驹溃,當(dāng)你子類化這個(gè)類時(shí),在子類的初始化方法里如果沒有正確地調(diào)用父類的designated initializer延曙,編譯器就會給出警告豌鹤。
實(shí)例代碼:

@interface WKWebView : UIView
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
@end

關(guān)于designated initializer更詳細(xì)的說明,參考:

  • Objective-C 拾遺:designated initializer
  • 正確編寫Designated Initializer的幾個(gè)原則

9.API版本控制

在更新接口枝缔,或者開發(fā)framework時(shí)傍药,需要標(biāo)明版本信息,告訴使用者此接口的平臺限制、操作系統(tǒng)版本拐辽、是否可用拣挪、是否已棄用等。
蘋果給出了幾個(gè)自帶的宏用于標(biāo)明版本俱诸,Xcode在檢測到錯(cuò)誤使用時(shí)會給出警告菠劝。只需要在方法名后面加上對應(yīng)的宏即可。

9.1 available

聲明本接口最低支持的操作系統(tǒng)版本睁搭。
當(dāng)你的接口使用了新系統(tǒng)的API赶诊,例如iOS8以上才有的UIAlertController,但是項(xiàng)目的deployment target卻是iOS7時(shí)园骆,需要標(biāo)明此接口的版本信息舔痪,讓使用者進(jìn)行兼容。
示例:

//SearchManager.h

typedef NS_ENUM(NSInteger,SearchState) {
    SearchStateNotSearch,
    SearchStateSearching,
    SearchStateSearchFinished,
    SearchStateSearchFailed
} NS_ENUM_AVAILABLE_IOS(2_0);//此枚舉在iOS2.0以上才能使用

NS_CLASS_AVAILABLE_IOS(2_0) //此類在iOS2.0以上才能使用
@interface SearchManager : NSObject
- (void)reSearch NS_AVAILABLE_IOS(5_0);//此方法在iOS5.0以上才能使用
@end

這幾個(gè)宏有對應(yīng)平臺的版本锌唾,例如NS_AVAILABLE_MAC, NS_AVAILABLE_IOS, NS_AVAILABLE_IPHONE锄码。
iOS10開始提供了新的available宏API_AVAILABLE,用來統(tǒng)一macOS晌涕、iOS滋捶、watchOS、tvOS幾個(gè)平臺余黎。

API_AVAILABLE(macos(10.10))
API_AVAILABLE(macos(10.9), ios(10.0))
API_AVAILABLE(macos(10.4), ios(8.0), watchos(2.0), tvos(10.0))

9.2 unavailable

聲明此接口不可用重窟,大多數(shù)時(shí)候是用于聲明所在平臺限制。
示例:

@interface SearchManager : NSObject
- (void)searchInWatch NS_UNAVAILABLE;//不能用此接口
- (void)searchInHostApp NS_EXTENSION_UNAVAILABLE_IOS;//extension里不能用此接口
- (void)search __TVOS_PROHIBITED;//tvOS里不能用此接口惧财,可修飾枚舉巡扇,類,方法垮衷,參數(shù)
@end

iOS10開始提供了新的unavailable宏API_UNAVAILABLE:

API_UNAVAILABLE(macos)
API_UNAVAILABLE(watchos, tvos)

9.3 deprecated

聲明此接口已經(jīng)被棄用霎迫,可以同時(shí)加注釋注明替代接口。
當(dāng)deployment target版本號設(shè)置成大于或等于方法被棄用的版本號時(shí)帘靡,Xcode會給出警告知给。
示例:

//注明廢棄類
NS_CLASS_DEPRECATED_IOS(2_0, 9_0, "UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead")
@interface UIAlertView : UIView
@end
//注明廢棄API
@interface UIViewController : UIResponder
- (void)viewDidUnload NS_DEPRECATED_IOS(3_0,6_0);
@end
//注明廢棄枚舉
typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
    UIStatusBarStyleDefault                                     = 0, // Dark content, for use on light backgrounds
    UIStatusBarStyleLightContent     NS_ENUM_AVAILABLE_IOS(7_0) = 1, // Light content, for use on dark backgrounds
    
    UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
    UIStatusBarStyleBlackOpaque      NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
}

iOS10開始提供了新的deprecated宏API_DEPRECATEDAPI_DEPRECATED_WITH_REPLACEMENT。前者可以注明棄用原因描姚,后者可以注明替代接口涩赢。

API_DEPRECATED("No longer supported", macos(10.4, 10.8))
API_DEPRECATED("No longer supported", macos(10.4, 10.8), ios(2.0, 3.0), watchos(2.0, 3.0), tvos(9.0, 10.0))

API_DEPRECATED_WITH_REPLACEMENT("-setName:", tvos(10.0, 10.4), ios(9.0, 10.0))
API_DEPRECATED_WITH_REPLACEMENT("SomeClassName", macos(10.4, 10.6), watchos(2.0, 3.0))

10.額外的修飾符

10.1 泛型

在聲明時(shí),對集合類型的對象增加泛型的修飾轩勘,就可以聲明集合內(nèi)存儲的數(shù)據(jù)類型筒扒。
例如:

@property (nonatomic, strong) NSMutableArray<NSString *> *myArray;

當(dāng)你向myArray里放入一個(gè)非NSString *類型的對象時(shí),編譯器會給出警告绊寻。

@property(nonatomic, strong) NSMutableArray<__kindof UIView *> * viewArray;

_kindof只限定了存儲類型為UIView花墩,因此也可以存儲UIView的子類悬秉,例如UIButton
更詳細(xì)的介紹冰蘑,參考:[Objective—C語言的新魅力——Nullability和泌、泛型集合與類型延拓

10.2 NS_REQUIRES_SUPER

NS_REQUIRES_SUPER宏用于聲明子類在重載父類的這個(gè)方法時(shí),需要調(diào)用父類的方法祠肥。例如:

- (void)viewWillAppear:(BOOL)animated NS_REQUIRES_SUPER;

10.3 NS_NOESCAPE

NS_NOESCAPE用于修飾方法中的block類型參數(shù)武氓,例如:

@interface NSArray: NSObject
- (NSArray *)sortedArrayUsingComparator:(NSComparator NS_NOESCAPE)cmptr
@end

作用是告訴編譯器,cmptr這個(gè)block在sortedArrayUsingComparator:方法返回之前就會執(zhí)行完畢仇箱,而不是被保存起來在之后的某個(gè)時(shí)候再執(zhí)行县恕。
類似于這樣的實(shí)現(xiàn):

- (void)performWithLock:(NS_NOESCAPE void (^)())block {  // exposed as @noescape to Swift
    [myLock lock];
    block();
    [myLock unlock];
}

編譯器知道之后,就會相應(yīng)地做一些優(yōu)化剂桥,例如去掉一些多余的對self的捕獲忠烛、retain、release操作权逗。因?yàn)閎lock的存活范圍僅限于本方法內(nèi)美尸,沒有必要再在block內(nèi)保留self了。
更詳細(xì)的介紹旬迹,參考這里

11.寫注釋

頭文件就是文檔求类,需要讓使用者快速知道這個(gè)類的作用奔垦。一個(gè)好的方法名可以讓使用者快速理解,但大部分時(shí)候還是需要相應(yīng)的注釋尸疆。
寫好格式化注釋后椿猎,當(dāng)光標(biāo)停留在方法名和屬性上時(shí),在Xcode右側(cè)的Quick Help欄里會出現(xiàn)注釋內(nèi)容寿弱,按住option并單擊犯眠,也會彈出注釋框。

11.1單行注釋

直接在方法或者屬性聲明的上一行使用///症革,后面加注釋筐咧,同時(shí)兼容Xcode和appleDoc。Xcode也支持//!噪矛,但是appleDoc不支持量蕊。

//SearchManagerBase.h

///搜索manager的基類
@interface SearchManagerBase : NSObject
///搜索狀態(tài)
@property (nonatomic, readonly) NSInteger * state;
@end

11.2多行注釋

多行注釋使用:

/**
 注釋內(nèi)容
*/

Xcode8提供了快速生成格式化注釋的快捷鍵:option+command+/。如果方法有參數(shù)艇挨,會自動添加@param關(guān)鍵字残炮,用于描述對應(yīng)的參數(shù)。
Apple提供了官方的headDoc語法缩滨,但是很多都已經(jīng)在Xcode中失效了势就,而且有些關(guān)鍵字也和appleDoc不兼容泉瞻。下面幾種列舉出了在Xcode中仍然有效的一些關(guān)鍵字:

/**
 演示蘋果headDoc的語法。這里可以寫方法簡介
 
 @brief 方法的簡介(appleDoc不支持此關(guān)鍵字)
 @discussion 方法的詳細(xì)說明
 
 @code //示例代碼(這個(gè)在Xcode里常用苞冯,但是appleDoc不支持此關(guān)鍵字)
 UIView *view;
 @endcode
 
 @bug       存在的bug的說明
 @note      需要注意的提示
 @warning   警告
 @since     iOS7.0
 @exception 方法會拋出的異常的說明
 
 @attention 注意袖牙,從這里開始往下的關(guān)鍵字,appleDoc都不支持
 @author    編寫者
 @copyright 版權(quán)
 @date      日期
 @invariant 不變量
 @post      后置條件
 @pre       前置條件
 @remarks   備注
 @todo      todo text
 @version   版本
 */
- (void)sampleMethod;

在Xcode中抱完,就會顯示為這樣:


comment.png

11.3 枚舉注釋

如果要給枚舉注釋贼陶,需要在每個(gè)枚舉值前注釋,按照如下格式:

///搜索狀態(tài)
typedef NS_ENUM(NSInteger,SearchState) {
    ///沒有開始搜索
    SearchStateNotSearch,
    ///搜索中
    SearchStateSearching,
    ///搜索結(jié)束
    SearchStateSearchFinished,
    ///搜索失敗
    SearchStateSearchFailed
};

11.4 幾個(gè)注釋約定

需要注釋的內(nèi)容:

  • 盡量為類添加描述巧娱,即便只有一句話碉怔。
  • 標(biāo)明某些參數(shù)和屬性的默認(rèn)值,比如超時(shí)time禁添。
  • 如果屬性是KVO兼容的撮胧,即外部可以使用KVO監(jiān)聽此屬性,則在屬性注釋里聲明老翘。
  • 回調(diào)block參數(shù)需要說明回調(diào)所在的線程芹啥,避免讓使用者在block里進(jìn)行多余的線程判斷。
  • 如果需要的話铺峭,說明使用此API需要的前置條件墓怀,防止被錯(cuò)誤地調(diào)用。
  • 對使用了method swizzling的API進(jìn)行統(tǒng)一形式的標(biāo)注卫键,方便遇到runtime的bug時(shí)進(jìn)行排查傀履。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市莉炉,隨后出現(xiàn)的幾起案子钓账,更是在濱河造成了極大的恐慌,老刑警劉巖絮宁,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梆暮,死亡現(xiàn)場離奇詭異,居然都是意外死亡绍昂,警方通過查閱死者的電腦和手機(jī)啦粹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窘游,“玉大人卖陵,你說我怎么就攤上這事≌欧澹” “怎么了泪蔫?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喘批。 經(jīng)常有香客問我撩荣,道長铣揉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任餐曹,我火速辦了婚禮逛拱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘台猴。我一直安慰自己朽合,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布饱狂。 她就那樣靜靜地躺著曹步,像睡著了一般。 火紅的嫁衣襯著肌膚如雪休讳。 梳的紋絲不亂的頭發(fā)上讲婚,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音俊柔,去河邊找鬼筹麸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雏婶,可吹牛的內(nèi)容都是我干的物赶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼留晚,長吁一口氣:“原來是場噩夢啊……” “哼酵紫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起倔丈,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤憨闰,失蹤者是張志新(化名)和其女友劉穎状蜗,沒想到半個(gè)月后需五,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡轧坎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年宏邮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缸血。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜜氨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捎泻,到底是詐尸還是另有隱情飒炎,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布笆豁,位于F島的核電站郎汪,受9級特大地震影響赤赊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜煞赢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一抛计、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧照筑,春花似錦吹截、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至媒抠,卻和暖如春弟断,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背趴生。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工阀趴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苍匆。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓刘急,卻偏偏與公主長得像,于是被迫代替她去往敵國和親浸踩。 傳聞我的和親對象是個(gè)殘疾皇子叔汁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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