NSProgress认识

34 篇文章 0 订阅
NSProgress是一个用来向用户不断传递某个任务进度的类。NSProgress类内部拥有一个进度报告机制。这使得代码很容易获取工作的进度、设置界面上以呈现进度。为进度条和提示文本提供数据支持,
进度条和提示文本会在进度变更时适当地更新。它还允许用户取消或暂停工作。

属性:
@property int64_t totalUnitCount; 工作总单元数,每个NSProgress对象对应一个工作,每一个工作都会按照某单位切分数个单元;

@property int64_t completedUnitCount; 已完成的单元数;

@property (readonly) double fractionCompleted; 等于“已完成的单元数”除以“工作总单元数”;

@property(copy) NSString *localizedDescription; 格式化fractionCompleted,eg:90% completed

@property(copy) NSString *localizedAdditionalDescription; 格式化completedUnitCount of totalUnitCount, eg:90 of 100

基本测试代码片段:
NSProgress *progress = [NSProgress new];
progress.totalUnitCount = 100;
progress.completedUnitCount = 90;
    
NSLog(@"%lld", progress.totalUnitCount );
NSLog(@"%lld", progress.completedUnitCount );
NSLog(@"%f", progress.fractionCompleted );

NSLog(@"%@", progress.localizedDescription );
NSLog(@"%@", progress.localizedAdditionalDescription );

控制台输出:
2019-11-22 09:52:16.321161+0800 AFN[17365:1053773] 100
2019-11-22 09:52:16.321595+0800 AFN[17365:1053773] 90
2019-11-22 09:52:16.321707+0800 AFN[17365:1053773] 0.900000
2019-11-22 09:52:16.334441+0800 AFN[17365:1053773] 90% completed
2019-11-22 09:52:16.335337+0800 AFN[17365:1053773] 90 of 100


通过KVO监听NSProgress的fractionCompleted属性值变化的代码片段(OC版的AFNetworking也有类似使用):
#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) NSProgress *progress;
@property (nonatomic, strong) NSTimer *timer;       //用来周期修改NSProgress的completedUnitCount值

@end

@implementation ViewController

- (void)dealloc
{
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
    
    [self.progress removeObserver:self forKeyPath:@"fractionCompleted"];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.progress = [NSProgress progressWithTotalUnitCount:100];
    [self.progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:(__bridge void * _Nullable)(self.progress)];
    
    __weak typeof(self) weakSelf = self;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:3 repeats:YES block:^(NSTimer * _Nonnull timer) {
        weakSelf.progress.completedUnitCount++;
    }];
    [self.timer fire];//立即fire
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (context == (__bridge void * _Nullable)(self.progress)) {
        NSLog(@"fractionCompleted = %.2f", self.progress.fractionCompleted);
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

@end


隐式添加子进度代码片段:
/*
- (void)becomeCurrentWithPendingUnitCount:(int64_t)unitCount; 
从当前进度对象中切分出一个子进度,当子进度完成当前进度分给的unitCount时,
当前进度的总量增加unitCount;
*/


/*
- (void)resignCurrent; 
与becomeCurrentWithPendingUnitCount配套使用, 在这两个方法中间需要设置至少一个子节点, 当子节点完成后, 总完成量会自动增加unitCount量, 
如果不设置子节点, 那么总任务完成量直接增加unitCount。
注意: 这两个方法成对出现, 并且必须在同一个队列中调用。
*/

#import "ImplicitlyViewController.h"

//派生子进度,添加进度标记属性。
@interface ChildProgress : NSProgress

@property (nonatomic, copy) NSString *identify;

@end

@implementation ChildProgress

@end

@interface ImplicitlyViewController ()

@property (nonatomic, strong) NSProgress *progress;//总进度

@end

@implementation ImplicitlyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.progress = [NSProgress progressWithTotalUnitCount:100];
    
    //本示例只分出了两层的进度树,也可以对子进度再切分,从而形成更多层树
    //分出50个任务量给任务一
    [self.progress becomeCurrentWithPendingUnitCount:50];
    [self subTask:@"任务一"];
    [self.progress resignCurrent];
    
    //分出50个任务量给任务二
    [self.progress becomeCurrentWithPendingUnitCount:50];
    [self subTask: @"任务二"];
    [self.progress resignCurrent];
}

- (void)subTask:(NSString *)identify
{
    //每个子任务的任务量分为100个单元, 每完成一个任务单元, 总任务完成量加上 50.0 / 100.0 = 0.5的任务单元
    ChildProgress *subProgress = (ChildProgress *)[ChildProgress progressWithTotalUnitCount:100];
    subProgress.identify = identify;
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(task:) userInfo:@{@"childProgress" : subProgress} repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)task:(NSTimer *)timer
{
    //获取当前的子进度
    NSDictionary *userInfo = timer.userInfo;
    ChildProgress *childProgress = userInfo[@"childProgress"];
    //当完成量达到总量时停止任务
    if (childProgress.completedUnitCount >= childProgress.totalUnitCount) {
        [timer invalidate];
        return;
    }
    //子进度完成自己的一个单元
    childProgress.completedUnitCount += 1;
    
    //打印
    NSLog(@"fractionCompleted --- %f, localizedDescription --- %@, localizedAdditionalDescription --- %@, identify:%@", self.progress.fractionCompleted, self.progress.localizedDescription, self.progress.localizedAdditionalDescription, childProgress.identify);
}

@end


显式添加子进度代码片段:
/*
+ (NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount parent:(NSProgress *)parent pendingUnitCount:(int64_t)portionOfParentTotalUnitCount
- (void)addChild:(NSProgress *)child withPendingUnitCount:(int64_t)inUnitCount
*/

#import "ExplicitViewController.h"

@interface ExplicitViewController ()

@property (nonatomic, strong) NSProgress *progress;

@end

@implementation ExplicitViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //设置总进度
    self.progress = [NSProgress progressWithTotalUnitCount:100];
    
    //显示获取两个子进度
    NSProgress *child1 = [NSProgress progressWithTotalUnitCount:100 parent:self.progress pendingUnitCount:50];
    NSProgress *child2 = [NSProgress progressWithTotalUnitCount:100 parent:self.progress pendingUnitCount:50];
    
    //使用定时器触发子进度
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(task:) userInfo:@{@"child1" : child1, @"child2" : child2} repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)task:(NSTimer *)timer
{
    //获取子进度
    NSDictionary *userInfo = timer.userInfo;
    NSProgress *child1 = userInfo[@"child1"];
    NSProgress *child2 = userInfo[@"child2"];
    //当子进度完成量达到总量时停止任务
    if (child1.completedUnitCount >= child1.totalUnitCount && child2.completedUnitCount >= child2.totalUnitCount) {
        [timer invalidate];
        return;
    }
    //子进度完成量+1
    child1.completedUnitCount += 1;
    NSLog(@"fractionCompleted --- %f, localizedDescription --- %@, localizedAdditionalDescription --- %@  --- child1", self.progress.fractionCompleted, self.progress.localizedDescription, self.progress.localizedAdditionalDescription);
    
    child2.completedUnitCount += 1;
    NSLog(@"fractionCompleted --- %f, localizedDescription --- %@, localizedAdditionalDescription --- %@  --- child2", self.progress.fractionCompleted, self.progress.localizedDescription, self.progress.localizedAdditionalDescription);
}


@end

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值