PINCache中的后臺任務

PINCache中的后臺任務

在PINCache磁盤緩存策略中,針對數(shù)據(jù)寫入,刪除等磁盤操作,作者用了后臺任務操作,用來確保磁盤操作得以順利完成。其具體是通過beginBackgroundTaskWithExpirationHandler來實現(xiàn)的。作者對其操作進行了封裝。在源碼中有一個PINBackgroundTask類,該類實現(xiàn)了向系統(tǒng)注冊后臺任務的方法。


這里有幾點需要明確下:
  • 大多數(shù)情況下,我們可以在app中通過調用beginBackgroundTaskWithExpirationHandler來請求一個后臺任務,通過調用endBackgroundTask來完成該請求。幾乎不會在用戶按下Home鍵的時候來調用。

  • 你可以在任何時候,同時向系統(tǒng)請求多個任務。這對于系統(tǒng)來說,性能損耗較低,就好比引用計數(shù)一樣,只要系統(tǒng)中還有一個未完成的請求,系統(tǒng)就會預留一些時間來完成它。

  • 系統(tǒng)是不能保證用戶的請求同步完成。這些方法只是向系統(tǒng)請求,系統(tǒng)仍可以忽略該請求,在需要一些額外的資源,甚至可能被系統(tǒng)然隨時殺了進程。系統(tǒng)通常會預留約10分鐘時間來處理請求。

動手寫一個
  1. 檢查系統(tǒng)是否支持多線程任務

     if([][UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupportes)]) {
    
     }
    
  2. 向系統(tǒng)請求一個后臺任務

     __block UIBackgroundTaskIdentifier background_task;
     background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
     //This code block is execute when the application’s 
     //remaining background time reaches ZERO.}];
    
  3. 執(zhí)行自己的異步操作,并標志請求完成

     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的具體實現(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;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容