總結(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_BEGIN
和NS_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_DEPRECATED
和API_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中抱完,就會顯示為這樣:
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)行排查傀履。