PINCache中的后臺任務(wù)
在PINCache磁盤緩存策略中际长,針對數(shù)據(jù)寫入想帅,刪除等磁盤操作,作者用了后臺任務(wù)操作队丝,用來確保磁盤操作得以順利完成。其具體是通過beginBackgroundTaskWithExpirationHandler來實(shí)現(xiàn)的欲鹏。作者對其操作進(jìn)行了封裝机久。在源碼中有一個PINBackgroundTask類,該類實(shí)現(xiàn)了向系統(tǒng)注冊后臺任務(wù)的方法赔嚎。
這里有幾點(diǎn)需要明確下:
大多數(shù)情況下膘盖,我們可以在app中通過調(diào)用beginBackgroundTaskWithExpirationHandler來請求一個后臺任務(wù),通過調(diào)用endBackgroundTask來完成該請求尤误。幾乎不會在用戶按下Home鍵的時候來調(diào)用侠畔。
你可以在任何時候,同時向系統(tǒng)請求多個任務(wù)损晤。這對于系統(tǒng)來說软棺,性能損耗較低,就好比引用計(jì)數(shù)一樣尤勋,只要系統(tǒng)中還有一個未完成的請求喘落,系統(tǒng)就會預(yù)留一些時間來完成它。
系統(tǒng)是不能保證用戶的請求同步完成最冰。這些方法只是向系統(tǒng)請求瘦棋,系統(tǒng)仍可以忽略該請求,在需要一些額外的資源锌奴,甚至可能被系統(tǒng)然隨時殺了進(jìn)程兽狭。系統(tǒng)通常會預(yù)留約10分鐘時間來處理請求。
動手寫一個
-
檢查系統(tǒng)是否支持多線程任務(wù)
if([][UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupportes)]) { }
-
向系統(tǒng)請求一個后臺任務(wù)
__block UIBackgroundTaskIdentifier background_task; background_task = [application beginBackgroundTaskWithExpirationHandler:^ { //This code block is execute when the application’s //remaining background time reaches ZERO.}];
-
執(zhí)行自己的異步操作鹿蜀,并標(biāo)志請求完成
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //### background task starts NSLog(@"Running in the background\n"); while(TRUE) { NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]); [NSThread sleepForTimeInterval:1]; //wait for 1 sec } //#### background task ends //Clean up code. Tell the system that we are done. [application endBackgroundTask: background_task]; background_task = UIBackgroundTaskInvalid; });
看看PINCache的具體實(shí)現(xiàn)
@interface PINBackgroundTask : NSObject
#if !defined(PIN_APP_EXTENSIONS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0
@property (atomic, assign) UIBackgroundTaskIdentifier taskID;
#endif
+ (instancetype)start;
- (void)end;
@end
@implementation PINBackgroundTask
- (instancetype)init
{
if (self = [super init]) {
#if !defined(PIN_APP_EXTENSIONS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0
_taskID = UIBackgroundTaskInvalid;
#endif
}
return self;
}
+ (instancetype)start
{
PINBackgroundTask *task = [[self alloc] init];
#if !defined(PIN_APP_EXTENSIONS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0
task.taskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
UIBackgroundTaskIdentifier taskID = task.taskID;
task.taskID = UIBackgroundTaskInvalid;
[[UIApplication sharedApplication] endBackgroundTask:taskID];
}];
#endif
return task;
}
- (void)end
{
#if !defined(PIN_APP_EXTENSIONS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0
UIBackgroundTaskIdentifier taskID = self.taskID;
self.taskID = UIBackgroundTaskInvalid;
[[UIApplication sharedApplication] endBackgroundTask:taskID];
#endif
}
@end
具體使用
- (void)removeObjectForKey:(NSString *)key fileURL:(NSURL **)outFileURL
{
if (!key)
return;
//創(chuàng)建一個后臺請求
PINBackgroundTask *task = [PINBackgroundTask start];
NSURL *fileURL = nil;
[self lock];
fileURL = [self encodedFileURLForKey:key];
[self removeFileAndExecuteBlocksForKey:key];
[self unlock];
//注銷完成該請求
[task end];
if (outFileURL) {
*outFileURL = fileURL;
}
}