1.示范文檔
首先看iOS Example
打開(kāi)Appdelegate文件
第一行代碼是
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
這個(gè)緩存類(lèi)以前沒(méi)有注意過(guò),也沒(méi)有用過(guò),打開(kāi)幫助文檔看看
Description:
Initializes an NSURLCache object with the specified values.(初始化一個(gè)NSURLCache實(shí)例)
Parameters:(參數(shù))
memoryCapacity:The memory capacity of the cache, in bytes.
(內(nèi)存緩存的容量:?jiǎn)挝粸閎ytes)
diskCapacity:The disk capacity of the cache, in bytes.
(硬盤(pán)緩存的容量:?jiǎn)挝粸閎ytes)
path:In OS X, path is the location at which to store the on-disk cache.
In iOS, path is the name of a subdirectory of the application’s default cache directory in which to store the on-disk cache (the subdirectory is created if it does not exist).
OS X存儲(chǔ)路徑在硬盤(pán) cache文件夾
iOS:在應(yīng)用的默認(rèn)cache文件夾子目錄下,如果子目錄不存在時(shí)會(huì)創(chuàng)建一個(gè)新的
創(chuàng)建了網(wǎng)絡(luò)緩存實(shí)例,內(nèi)存緩存4M, 硬盤(pán)緩存為20M,路徑為默認(rèn)nil
這個(gè)日后再深入研究吧,不知道內(nèi)存、硬盤(pán)都滿(mǎn)了會(huì)發(fā)生什么情況
再看下面一句
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
屬于UIKit+AFNetworking里面的類(lèi)
點(diǎn)進(jìn)去發(fā)現(xiàn)注釋非常詳細(xì),都是英文,慢慢啃吧
AFNetworkActivityIndicatorManagermanages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
AFNetworkActivityIndicatorManager類(lèi)是管理狀態(tài)欄上的網(wǎng)絡(luò)指示器,就是那個(gè)會(huì)轉(zhuǎn)的小菊花。當(dāng)設(shè)置enabled屬性為YES,它會(huì)接受session task(會(huì)話(huà)層任務(wù)?)的通知,當(dāng)任務(wù)結(jié)束、開(kāi)始或則指示器會(huì)相應(yīng)地以動(dòng)畫(huà)的形式開(kāi)始轉(zhuǎn)或者消失,如果網(wǎng)絡(luò)任務(wù)請(qǐng)求數(shù)量大于零,指示器將會(huì)持續(xù)轉(zhuǎn)一段時(shí)間
You should enable the shared instance of
AFNetworkActivityIndicatorManagerwhen your application finishes launching. InAppDelegate application:didFinishLaunchingWithOptions:you can do so with the following code:
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
這段話(huà)是教怎么用這個(gè)類(lèi)的,在應(yīng)用啟動(dòng)之后就在AppDelegate application:didFinishLaunchingWithOptions:方法內(nèi)調(diào)用
By setting
enabledtoYESforsharedManager, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to callincrementActivityCountordecrementActivityCountyourself.
只要設(shè)置enabled屬性為YES,這個(gè)類(lèi)就會(huì)自動(dòng)處理指示器出現(xiàn)和消失,不需要調(diào)用incrementActivityCount和decrementActivityCount這兩個(gè)參數(shù)
NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.")
iOS8新特性,擴(kuò)展,Today視圖之類(lèi)的,不能在擴(kuò)展中使用
@property (nonatomic, assign) NSTimeInterval activationDelay;
這個(gè)參數(shù)有點(diǎn)意思,按照蘋(píng)果人機(jī)交互原則,如果網(wǎng)絡(luò)請(qǐng)求過(guò)快就不需要顯示菊花轉(zhuǎn),默認(rèn)值為1秒,這個(gè)參數(shù)猜測(cè)應(yīng)該是少于1秒的請(qǐng)求就不顯菊花,接下來(lái)在實(shí)現(xiàn)文件中再研究
@property (nonatomic, assign) NSTimeInterval completionDelay;
和activationDelay相對(duì)應(yīng),如果有多個(gè)請(qǐng)求,指示器為了連貫,會(huì)有一個(gè)延遲消失的時(shí)間,默認(rèn)為0.17秒
- (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block;
這個(gè)方法在指示器即將出現(xiàn)、消失時(shí)調(diào)用,調(diào)用這個(gè)方法可以通過(guò)block自定義某些邏輯,默認(rèn)是null,manager會(huì)自動(dòng)管理指示器的出現(xiàn),消失,如果設(shè)置了block,需要手動(dòng)管理,其實(shí)就是調(diào)用系統(tǒng)的方法:[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:networkActivityIndicatorVisible];
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
蘋(píng)果為了和swift的可選類(lèi)型兼容設(shè)定的宏,用了這兩個(gè)宏,它們中間的方法參數(shù)默認(rèn)為_(kāi)_nonnull,只需要為特定的參數(shù)設(shè)置__nullable就可以了
實(shí)現(xiàn)文件:
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
AFNetworkActivityManagerStateNotActive,
AFNetworkActivityManagerStateDelayingStart,
AFNetworkActivityManagerStateActive,
AFNetworkActivityManagerStateDelayingEnd
};
static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0;
static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17;
按照OC規(guī)范定義了四個(gè)枚舉和兩個(gè)常量,之前所說(shuō)的按照apple人機(jī)交互原則設(shè)定
+ (instancetype)sharedManager {
static AFNetworkActivityIndicatorManager *_sharedManager = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedManager = [[self alloc] init];
});
return _sharedManager;
}
標(biāo)準(zhǔn)的單例寫(xiě)法
接下來(lái)主要探討一下網(wǎng)絡(luò)請(qǐng)求多任務(wù)下指示器的工作
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}
self.currentState = AFNetworkActivityManagerStateNotActive;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidSuspendNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil];
self.activationDelay = kDefaultAFNetworkActivityManagerActivationDelay;
self.completionDelay = kDefaultAFNetworkActivityManagerCompletionDelay;
return self;
}
首先在初始化方法里設(shè)置了三個(gè)通知,通過(guò)currentState來(lái)控制指示器的狀態(tài)
看一下請(qǐng)求開(kāi)始的時(shí)候通知方法
1.在networkRequestDidStart:方法接收通知,驗(yàn)證請(qǐng)求地址,activityCount+1
2.主線程下更新currentState,設(shè)置開(kāi)始延時(shí)定時(shí)器[self startActivationDelayTimer],定時(shí)器加入到NSRunLoopCommonModes的runloop
3.定時(shí)器到時(shí)方法activationDelayTimerFired,通過(guò)networkActivityOccurring(activityCount是否 > 0)屬性判斷CurrentState狀態(tài),如果activityCount>0,把currentState設(shè)置為AFNetworkActivityManagerStateActive
4.最后通過(guò)setNetworkActivityIndicatorVisible方法展現(xiàn)指示器
請(qǐng)求結(jié)束的通知方法:
1.networkRequestDidFinish:方法接收通知,驗(yàn)證請(qǐng)求地址,activityCount-1,當(dāng)activityCount == 0,狀態(tài)會(huì)有所變化
2.主線程下更新CurrentState,設(shè)置結(jié)束延時(shí)定時(shí)器[self startCompletionDelayTimer],定時(shí)器加入到NSRunLoopCommonModes的runloop
3.定時(shí)器到時(shí)方法completionDelayTimerFired,調(diào)用[self setCurrentState:AFNetworkActivityManagerStateNotActive];設(shè)置currentState為無(wú)活動(dòng)
4.關(guān)閉定時(shí)器
[self cancelActivationDelayTimer]; [self cancelCompletionDelayTimer];
調(diào)用setNetworkActivityIndicatorVisible:方法使指示器菊花消失
指示器實(shí)現(xiàn)方法大概就是這樣了,順帶說(shuō)一下,session task通知是由AFURLSessionManager類(lèi)發(fā)出的異步通知
還有就是有一點(diǎn)不明白的地方,AFN使用了很多KVO手動(dòng)通知
比如說(shuō):
[self willChangeValueForKey:@"networkActivityIndicatorVisible"];
[self didChangeValueForKey:@"networkActivityIndicatorVisible"];
這一對(duì),但是沒(méi)有看見(jiàn)設(shè)置了觀察者和關(guān)閉自動(dòng)通知的方法。不知道設(shè)置kvo手動(dòng)通知的原因是什么