自定义NSOperation

12 阅读2分钟

1) NSInvocationOperation和NSBlockOperation不能满足我们的需求时就需要我们自定义,自定义NSOperation的场景主要是为了我们能更好的控制一个任务,什么情况下开始、取消、完成, 并且可以分离代码的实现

2) 实现步骤:(可参考下面代码)

(1)实现start方法

(2)重写isAsynchronous,是否为并发任务、根据自己的情况即可

(3)main方法可根据自己的实际需要决定是否实现、一般实现并在里面做自己的事

(4)finished、executing更新任务的状态,用于触发KVO

(5)自己的任务完成后,一定要把当前的任务状态改为完成,否则队列中后面的任务,将永远不会执行


@property(assign, nonatomic, getter=isFinished) BOOL finished;
@property(assign, nonatomic, getter=isExecuting) BOOL executing;
@property(assign, nonatomic, getter=isStart) BOOL start;
@property(assign, nonatomic, getter=isFinished) BOOL finished;
@property(assign, nonatomic, getter=isExecuting) BOOL executing;
@property(assign, nonatomic, getter=isStart) BOOL start;

@implementation CustomOperation

@synthesize finished = _finished, executing = _executing;

- (BOOL)isAsynchronous {
    return NO;
}

- (void)setFinished:(BOOL)finished {
    [self willChangeValueForKey:@"finished"];
    _finished = finished;
    [self didChangeValueForKey:@"finished"];
}

- (void)setExecuting:(BOOL)executing {
    [self willChangeValueForKey:@"executing"];
    _executing = executing;
    [self didChangeValueForKey:@"executing"];
}

- (void)start {
    @synchronized (self) {
        self.start = YES;
        if (self.isCancelled) {
            [self completed];
            return;
        }
        @autoreleasepool {
            [self main];
        }
        self.executing = YES;
    }
}

- (void)main {//在此处做一些更复杂的操作
    NSLog(@"准备开始执行任务啦~ %@", [NSThread currentThread]);
    //模拟3s后执行doSomething
    [self performSelector:@selector(doSomething:) withObject:nil afterDelay:3.0];
    [[NSRunLoop currentRunLoop] run];//此处需要添加到Runloop,子线程默认没有开启,后期文章会具体说明
}

- (void)doSomething:(id)obj {
    NSLog(@"完成了当前的任务!%@", [NSThread currentThread]);
    [self completed];
}

- (void)completed {
    @synchronized (self) {
        self.executing = NO;
        self.finished = YES;
    }
}

- (void)cancel {
    [super cancel];
    if (self.isStart) {
        [self completed];
    }
}

@end
@implementation CustomOperation

@synthesize finished = _finished, executing = _executing;

- (BOOL)isAsynchronous {
    return NO;
}

- (void)setFinished:(BOOL)finished {
    [self willChangeValueForKey:@"finished"];
    _finished = finished;
    [self didChangeValueForKey:@"finished"];
}

- (void)setExecuting:(BOOL)executing {
    [self willChangeValueForKey:@"executing"];
    _executing = executing;
    [self didChangeValueForKey:@"executing"];
}

- (void)start {
    @synchronized (self) {
        self.start = YES;
        if (self.isCancelled) {
            [self completed];
            return;
        }
        @autoreleasepool {
            [self main];
        }
        self.executing = YES;
    }
}

- (void)main {//在此处做一些更复杂的操作
    NSLog(@"准备开始执行任务啦~ %@", [NSThread currentThread]);
    //模拟3s后执行doSomething
    [self performSelector:@selector(doSomething:) withObject:nil afterDelay:3.0];
    [[NSRunLoop currentRunLoop] run];//此处需要添加到Runloop,子线程默认没有开启,后期文章会具体说明
}

- (void)doSomething:(id)obj {
    NSLog(@"完成了当前的任务!%@", [NSThread currentThread]);
    [self completed];
}

- (void)completed {
    @synchronized (self) {
        self.executing = NO;
        self.finished = YES;
    }
}

- (void)cancel {
    [super cancel];
    if (self.isStart) {
        [self completed];
    }
}

@end

运行结果:

准备开始执行任务啦~ <NSThread: 0x600000b58380>{number = 8, name = (null)}

完成了当前的任务!<NSThread: 0x600000b58380>{number = 8, name = (null)}