1.什么是業(yè)務類?
業(yè)務類:專門處理某項業(yè)務(事情)
2.業(yè)務類的作用?
把一些業(yè)務的業(yè)務邏輯封裝起來,其它類需要處理這些業(yè)務的時候,直接調(diào)用業(yè)務類的方法就可以了
大大減少了其它類中的代碼量,讓代碼看起來更整潔,可讀性更好
3.業(yè)務類的規(guī)范
3.1 在類的上面,注明這個類的功能(作用)
讓其它人一看到這個類就知道是干什么用的,減少溝通成本
// Created by xiaomage on 16/7/31.
// Copyright ? 2016年 XiaoMaG. All rights reserved.
// 專門處理文件 (標注方式一)
/**
*專門處理文件 (標注方式二)
*/
@interface XTFileManager : NSObject
3.2 每個方法或?qū)傩?都需要使用文檔注釋
讓其他人能快速掌握這個類怎么用,減少溝通成本
/**
*
*作用:指定一個文件夾路徑,獲取文件夾尺寸
*參數(shù)(directoryPath):文件夾路徑
*返回值:文件夾尺寸 */
+(NSInteger)getSizeOfDirectoryPath:(NSString *)directoryPath;
3.3 每個方法一定要嚴謹
如果別人不按照方法的規(guī)定方式來使用,就報錯(拋異常),這樣別人就不會認為是方法的問題,能更好的處理錯誤
例如做一些必要的判斷:判斷傳入的內(nèi)容不是我們需要的格式,就拋異常
> // 判斷下是否是隱藏文件
if ([subPath hasPrefix:@".DS"]) continue;
// 是否是文件夾 BOOL isDirectory;
// 判斷文件是否存在,并且是否是文件夾
[mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if (isDirectory) continue;
3.4 怎么拋異常?
> if (!isExist || !isDirectory) {
// 拋異常:NSException
// name:異常名稱
// reason:異常原因
方式一: //NSException *excp = [NSException exceptionWithName:@"FileError" reason:@"笨蛋,傳入的路徑可
能為空,或者不是文件夾路徑,仔細好好檢查吧" userInfo:nil];
//[excp raise];
方式二:@throw [NSException exceptionWithName:@"FileError" reason:@"笨蛋,傳入的路徑可能為空,或者不
是文件夾路徑,仔細好好檢查吧" userInfo:nil];
}
4.怎么封裝業(yè)務類?
4.1第一種方法:常規(guī)方法封裝,直接把方法的聲明和實現(xiàn)拷貝到業(yè)務類中
缺點: 計算文件夾緩存尺寸,如果文件里面子文件比較多,比較耗時
+ (void)removeDirectory:(NSString *)directoryPath
{
NSFileManager *mgr = [NSFileManager defaultManager];
BOOL isDirectory;
BOOL isExist = [mgr fileExistsAtPath:directoryPath isDirectory:&isDirectory];
if (!isExist || !isDirectory) {
// 拋異常:NSException
@throw [NSException exceptionWithName:@"FileError" reason:@"笨蛋,傳入的路徑可能為空,或者不是文
件夾路徑,仔細好好檢查吧" userInfo:nil];
}
// 1.刪除Cache文件夾
[mgr removeItemAtPath:directoryPath error:nil];
// 2.創(chuàng)建新Cache文件夾
[mgr createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:nil];
}
+ (NSInteger)getSizeOfDirectoryPath:(NSString *)directoryPath
{
// 1.獲取文件管理者對象
NSFileManager *mgr = [NSFileManager defaultManager];
// 判斷傳入文件夾路徑存在
BOOL isDirectory;
BOOL isExist = [mgr fileExistsAtPath:directoryPath isDirectory:&isDirectory];
if (!isExist || !isDirectory) {
// 拋異常:NSException
// name:異常名稱
// reason:異常原因
//NSException *excp = [NSException exceptionWithName:@"FileError" reason:@"笨蛋,傳入的路徑可能為
空,或者不是文件夾路徑,仔細好好檢查吧" userInfo:nil];
// [excp raise];
@throw [NSException exceptionWithName:@"FileError" reason:@"笨蛋,傳入的路徑可能為空,或者不是文件
夾路徑,仔細好好檢查吧" userInfo:nil];
}
NSInteger totalSize = 0;
// 2.獲取所有文件(傳遞文件夾路徑)
// Path:文件夾路徑
// subpathsAtPath:獲取一個文件夾中所有子路徑,包含多級路徑
NSArray *subPaths = [mgr subpathsAtPath:directoryPath];
// 3.遍歷所有文件
for (NSString *subPath in subPaths) {
// 4.拼接完整文件名
NSString *filePath = [directoryPath stringByAppendingPathComponent:subPath];
// 判斷下是否是隱藏文件
if ([subPath hasPrefix:@".DS"]) continue;
// 是否是文件夾
BOOL isDirectory;
// 判斷文件是否存在,并且是否是文件夾
[mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if (isDirectory) continue;
// 5.attributesOfItemAtPath:傳入文件全路徑,就能獲取文件屬性
NSDictionary *attr = [mgr attributesOfItemAtPath:filePath error:nil];
// 6.把文件尺寸累加
totalSize += [attr fileSize];
}
return totalSize;
}
4.2 第二種方法:block封裝業(yè)務類 開啟子線程,把耗時操作放到子線程中執(zhí)行
注意:刷新UI的操作一定要回到主線程執(zhí)行 ,
用block作為參數(shù),開啟異步任務,一定不要返回數(shù)據(jù)
4.3 為什么使用block作為參數(shù),開啟異步任務,一定不要返回數(shù)據(jù)?
異步函數(shù)的特點:
01 具備開線程的能力
02 執(zhí)行任務的方式:異步
異步執(zhí)行:我開始執(zhí)行后,可以不用等我執(zhí)行完,就執(zhí)行后面的任務
由于異步函數(shù)異步執(zhí)行,如果有返回值,返回值要放到主線程中執(zhí)行,
那么執(zhí)行到異步函數(shù)的時候,會直接跳過異步函數(shù)執(zhí)行返回操作,這個時候返回值還沒計算出來,會造成數(shù)據(jù)錯亂
4.4 怎么解決block作為參數(shù),外界需要返回值的問題?
讓帶有參數(shù)的block 作為參數(shù),把需要返回的數(shù)據(jù),賦值給block的參數(shù),讓blcok傳遞出去就就可以了
4.5 block作為參數(shù)的格式怎么寫?
如果不會的話,就把AFN里面的block參數(shù)拷過來改一下
-(NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))downloadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
// 異步任務,不要返回數(shù)據(jù)
+(void)getSizeOfDirectoryPath:(NSString *)directoryPath completion:(void (^)(NSInteger totalSize))completion
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 子線程執(zhí)行
// 1.獲取文件管理者對象
NSFileManager *mgr = [NSFileManager defaultManager];
// 判斷傳入文件夾路徑存在
BOOL isDirectory;
BOOL isExist = [mgr fileExistsAtPath:directoryPath isDirectory:&isDirectory];
if (!isExist || !isDirectory) {
@throw [NSException exceptionWithName:@"FileError" reason:@"笨蛋,傳入的路徑可能為空,或者不是文件夾路徑,仔細好好檢查吧" userInfo:nil];
}
NSInteger totalSize = 0;
// 2.獲取所有文件(傳遞文件夾路徑)
NSArray *subPaths = [mgr subpathsAtPath:directoryPath];
// 3.遍歷所有文件
for (NSString *subPath in subPaths) {
// 4.拼接完整文件名
NSString *filePath = [directoryPath stringByAppendingPathComponent:subPath];
// 判斷下是否是隱藏文件
if ([subPath hasPrefix:@".DS"]) continue;
// 是否是文件夾
BOOL isDirectory;
// 判斷文件是否存在,并且是否是文件夾
[mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if (isDirectory) continue;
// 5.attributesOfItemAtPath:傳入文件全路徑,就能獲取文件屬性
NSDictionary *attr = [mgr attributesOfItemAtPath:filePath error:nil];
// 6.把文件尺寸累加
totalSize += [attr fileSize];
}
// 一定要記得回到主線程 dispatch_sync(dispatch_get_main_queue(), ^{
if (completion) {
注意:()內(nèi)可以寫這個方法定義的任何值,但要和block的參數(shù)類型相同,最后括號內(nèi)的值會傳給Block的參數(shù)
completion(totalSize);
}
});
});
}