1.什么是业务类?
业务类:专门处理某项业务(事情)
2.业务类的作用?
把一些业务的业务逻辑封装起来,其它类需要处理这些业务的时候,直接调用业务类的方法就可以了
大大减少了其它类中的代码量,让代码看起来更整洁,可读性更好
3.业务类的规范
3.1 在类的上面,注明这个类的功能(作用)
让其它人一看到这个类就知道是干什么用的,减少沟通成本
// Created by xiaomage on 16/7/31.
// Copyright © 2016年 XiaoMaG. All rights reserved.
// 专门处理文件 (标注方式一)
/**
*专门处理文件 (标注方式二)
*/
@interface XTFileManager : NSObject
3.2 每个方法或属性,都需要使用文档注释
让其他人能快速掌握这个类怎么用,减少沟通成本
/**
*
*作用:指定一个文件夹路径,获取文件夹尺寸
*参数(directoryPath):文件夹路径
*返回值:文件夹尺寸 */
+(NSInteger)getSizeOfDirectoryPath:(NSString *)directoryPath;
3.3 每个方法一定要严谨
如果别人不按照方法的规定方式来使用,就报错(抛异常),这样别人就不会认为是方法的问题,能更好的处理错误
例如做一些必要的判断:判断传入的内容不是我们需要的格式,就抛异常
> // 判断下是否是隐藏文件
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.怎么封装业务类?
4.1第一种方法:常规方法封装,直接把方法的声明和实现拷贝到业务类中
缺点: 计算文件夹缓存尺寸,如果文件里面子文件比较多,比较耗时
+ (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.创建新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封装业务类 开启子线程,把耗时操作放到子线程中执行
注意:刷新UI的操作一定要回到主线程执行 ,
用block作为参数,开启异步任务,一定不要返回数据
4.3 为什么使用block作为参数,开启异步任务,一定不要返回数据?
异步函数的特点:
01 具备开线程的能力
02 执行任务的方式:异步
异步执行:我开始执行后,可以不用等我执行完,就执行后面的任务
由于异步函数异步执行,如果有返回值,返回值要放到主线程中执行,
那么执行到异步函数的时候,会直接跳过异步函数执行返回操作,这个时候返回值还没计算出来,会造成数据错乱
4.4 怎么解决block作为参数,外界需要返回值的问题?
让带有参数的block 作为参数,把需要返回的数据,赋值给block的参数,让blcok传递出去就就可以了
4.5 block作为参数的格式怎么写?
如果不会的话,就把AFN里面的block参数拷过来改一下
-(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
// 异步任务,不要返回数据
+(void)getSizeOfDirectoryPath:(NSString *)directoryPath completion:(void (^)(NSInteger totalSize))completion
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 子线程执行
// 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) {
注意:()内可以写这个方法定义的任何值,但要和block的参数类型相同,最后括号内的值会传给Block的参数
completion(totalSize);
}
});
});
}