block的應用場景

分類:技術 時間:2016-10-25

今天來說下block的一個重要的用法,在此之前,我們先來認識下block,block也是一種數據類型,只不過它用來保存一段代碼.

聲明一個無返回值,無形參的block的代碼如下:

void(^block)();其中void表示沒有返回值,block表示變量名,^可以當做是block的一個標志識,后面一個括號表示沒有形參.

定義一個無返回值,無形參的block的代碼如下:

void(^block)() = ^(){ };等號后面的圓括號表示形參,特別說明,等號后面的圓括號要傳入形參時必須包含形參類型及名稱,因為傳入的形參是需要在后面的大括號內調用的.

定義一個有返回值,有形參的block的代碼如下:

int(^block1)(int) = ^int(int a){

return a;

};每個部分表示的含義參考上面的即可

調用一個block的代碼如下:

block1(5),參考上一個代碼,返回的結果為5,當無形參時,圓括號內的參數不用填.

接下來說說一個重要的用法,當程序遇到一些耗時的操作的時候,我們通常會開啟一個子線程來執行這段代碼,當用GCD開子線程就得用到異步函數,當遇到這個耗時操作有返回值的時候,由于異步函數里任務是異步執行的,系統執行到這個耗時操作的時候可能會先跳過,不會立馬返回結果(所以通常用異步函數是沒有返回值的),那么對于需要用到這個返回值的那些代碼,由于拿不到該返回值,執行的時候就不是我們預期的了,那么怎么解決呢?這時候我們就要用到block了,我們可以把外界那些需要用到這個返回值的代碼包裝成一個block傳入到異步函數內,異步函數內就有外界需要的返回值了,也就是我們說的回調.

下面以一個獲取一個文件夾的大小為例來說明一下這個block的應用:

(void)getDirectorySize:(NSString *)directoryPath completion:(void(^)(int))completion

{

// GCD開啟一個子線程

dispatch_async(dispatch_get_global_queue(0, 0), ^{

// 創建文件管理者

NSFileManager *mgr = [NSFileManager defaultManager];

BOOL isDirectory = NO;

BOOL isExists = [mgr fileExistsAtPath:directoryPath isDirectory:amp;isDirectory];

if (!isExists || !isDirectory) {

// 報錯:拋異常

NSException *excp = [NSException exceptionWithName:@quot;FileErrorquot; reason:@quot;傳入路徑不存在,或者不是文件夾路徑quot; userInfo:nil];

[excp raise];

}

// 獲取文件夾所有子路徑數組:獲取多級目錄下文件路徑

NSArray *subpaths = [mgr subpathsAtPath:directoryPath];

// 遍歷

int totalSize = 0;

for (NSString *subPath in subpaths) {

NSString *filePath = [directoryPath stringByAppendingPathComponent:subPath];

// 判斷是否是隱藏文件

if ([filePath containsString:@quot;.DSquot;]) continue;

// 判斷是否是文件夾

BOOL isDirectory = NO;

BOOL isExists = [mgr fileExistsAtPath:filePath isDirectory:amp;isDirectory];

if (!isExists || isDirectory) continue;

// 獲取文件屬性

NSDictionary *attr = [mgr attributesOfItemAtPath:filePath error:nil];

totalSize = [attr fileSize];

}

dispatch_sync(dispatch_get_main_queue(), ^{

if (completion) {

completion( totalSize );

}

});

});

}

注意:當得到文件的大小totalSize時,我們有可能需要把它顯示給用戶看,這時候可能由于我們在這個類里面拿不到相應的控件來顯示數據,那么我們就需要把這個totalSize傳出去,這個時候block就派上用場了,我們可以在寫得到文件夾大小的方法的時候讓外界傳入一個block,然后我們拿到外界傳入的block再進行回調就可以了,以上回調的代碼是:completion(totalSize);這樣外界就可以間接的拿到totalSize這個數據了.

如有錯誤的地方,期待您的糾正!

PS:如果對于獲取一個文件夾大小有疑問的可以看我下一篇,謝謝!


Tags: iOS開發

文章來源:http://www.jianshu.com/p/b8d46c116c3e


ads
ads

相關文章
ads

相關文章

ad