注册
iOS

iOS Operation 自定义的注意点

问题


  • 碰到一个问题,就是做一个点击后添加动画效果,连续点击则有多个动画效果按顺序执行,通过自定Operation,以队列实现,但是发现每次点击玩上次动画效果还没完全执行完点击之后的动画就出来,不符合需求。
  • 后来查资料得知自定义Operation中有两个属性分别表示任务是否在执行以及是否执行完毕,如下

@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
复制代码


因此在自定义Operation时设置这两个属性,同时在完全当前队列中任务时给予标识表明任务完成,具体代码如下




  • CustomOperation 类

@interface CustomOperation : NSOperation

@end

#import "CustomOperation.h"

@interface CustomOperation ()

@property(nonatomic,readwrite,getter=isExecuting)BOOL executing; // 表示任务是否正在执行
@property(nonatomic,readwrite,getter=isFinished)BOOL finished; // 表示任务是否结束

@end

@implementation CustomOperation

@synthesize executing = _executing;
@synthesize finished = _finished;

- (void)start
{
    @autoreleasepool {
        self.executing = YES;
        if (self.cancelled) {
            [self done];
            return;
        }
        // 执行任务
        __weak typeof(self) weakSelf = self;
        dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
        dispatch_after(delayTime, dispatch_get_main_queue(), ^{
            NSLog(@"动画完毕");
            // 任务执行完毕手动关闭
            [weakSelf done];
        });
    }
}

-(void)done
{
    self.finished = YES;
    self.executing = NO;
}

#pragma mark - setter -- getter
// 监听并设置executing
- (void)setExecuting:(BOOL)executing
{
    [self willChangeValueForKey:@"isExecuting"];
    _executing = executing;
    [self didChangeValueForKey:@"isExecuting"];
}

- (BOOL)isExecuting
{
    return _executing;
}

// 监听并设置finished
- (void)setFinished:(BOOL)finished
{
    if (_finished != finished) {
        [self willChangeValueForKey:@"isFinished"];
        _finished = finished;
        [self didChangeValueForKey:@"isFinished"];
    }
}

- (BOOL)isFinished
{
    return _finished;
}

// 返回YES 标识并发Operation
- (BOOL)isAsynchronous
{
    return YES;
}

@end


  • swift版

class AnimationOperation: Operation {

    var animationView:AnimationView? // 动画view
    var superView:UIView? // 父视图
    var finishCallBack:(()->())? // 完成动画的回调

    override var isExecuting: Bool {
        return operationExecuting
    }

    override var isFinished: Bool {
        return operationFinished
    }

    override var isAsynchronous: Bool {
        return true
    }
// 监听
    private var operationFinished:Bool = false {
        willSet {
            willChangeValue(forKey: "isFinished")
        }
        didSet {
            didChangeValue(forKey: "isFinished")
        }
    }

    private var operationExecuting:Bool = false {
        willSet {
            willChangeValue(forKey: "isExecuting")
        }
        didSet {
            didChangeValue(forKey: "isExecuting")
        }
    }

// 每次点击添加动画队列
    class func addOperationShowAnimationView(animationView:AnimationView,superView:UIView) -> AnimationOperation {

        let operation = AnimationOperation()
        operation.animationView = animationView
        operation.superView = superView
        return operation
    }

    override func start() {
        self.operationExecuting = true
        if isCancelled == true {
            self.done()
            return
        }

        guard let superView = self.superView,
              let subView = self.animationView,
              let callback = self.finishCallBack else {
            print("superView == nil")
            return
        }

        OperationQueue.main.addOperation {[weak self] in
            superView.addSubview(subView)
            subView.finishCallBack = {
                self?.done()
                callback()
            }
            subView.showAnimation()
        }
    }

    

    private func done() {
        self.operationFinished = true
        self.operationExecuting = false
    }

}

作者:取个有意思的昵称
链接:https://juejin.cn/post/7034518171314815007

0 个评论

要回复文章请先登录注册