自定义NSOperation

对于NSOperation.如果要自定义的话,我们需要重写Start或者main.

对于start方法
If you are implementing a concurrent operation, you must override this method and use it to initiate your operation. Your custom implementation must not call super at any time.

对于main方法
If you are implementing a concurrent operation, you are not required to override this method but may do so if you plan to call it from your custom start method.

就是说如果咱们自定义的是并发的NSOperation.那么我们得重写start方法.如果是串行的话就需要重写main方法.

AFNetWorking的例子

我们知道在AFN3.0以上AFN完全替换成了NSURLSession.在3.0以下全都使用NSURLConnection.在3.0以下用的是自定义的NSOperation.3.0以上用的是系统提供的.

图片一(AFURLConnectionOperation结构)

我们可以看出来.这个自定义NSOperation没有重写main方法.并且使用了NSRecursiveLock(递归锁)来执行锁定、解锁操作

递归锁拓展

NSRecursiveLock(递归锁)的好处是可以多次加锁不会造成崩溃.只有lockunlock平衡了之后锁定的资源才会被释放.

可以看得出来AFNetworking子类化的AFURLConnectionOperation是并发的.

图片二(AFURLConnectionOperation在NSOperation分类的结构).

看得出来.NSOperation的状态都重新实现了

2.串行操作

必须复写- (void)main;方法

示例:

// MARK: CHOperationSERIAL.h

typedef NS_ENUM(NSUInteger, CHOperationSERIALState) {
    CHOperationSERIALStateUnknow,
    CHOperationSERIALStateReadyToStart,
    CHOperationSERIALStateFinish,
};

@interface CHOperationSERIAL : NSOperation

@property (nonatomic ,assign) CHOperationSERIALState state;

@property (nonatomic ,assign) NSInteger count;

@end

// MAKR: CHOperationSERIAL.m

@interface CHOperationSERIAL ()

@property (nonatomic ,strong) NSRecursiveLock *lock;

@end

@implementation CHOperationSERIAL

- (NSRecursiveLock *)lock {
    if (!_lock) {
        _lock = [[NSRecursiveLock alloc] init];
    }
    return _lock;
}

- (void)main {
    [self.lock lock];
    if (self.isCancelled) {
        [self operationDidCancel];
    } else if (self.isReady) {
        [self operationDidStart];
    }
    [self.lock unlock];
}

- (void)operationDidCancel {
    NSLog(@"count:%ld func:%s", self.count ,__FUNCTION__);
}

- (void)operationDidStart {
    NSLog(@"start: count:%ld %@", self.count ,[NSThread currentThread]);
    [NSThread sleepForTimeInterval:arc4random_uniform(10)];
    NSLog(@"end: count:%ld %@", self.count ,[NSThread currentThread]);
    self.state = CHOperationSERIALStateFinish;
}

注意:使用的时候NSOperationQueue的最大并发数(maxConcurrentOperationCount)要设置为1

3. 并行操作

并行操作需要重写下面四个方法.

start

asynchronous (这个需要返回YES)

executing // 执行

finished // 完成(不返回YES就不会dealloc)
/// CHOperation.h
typedef NS_ENUM(NSUInteger, CHOperationState) {
    CHOperationStateUnknow,
    CHOperationStateReadyToStart,
    CHOperationStateFinish,
};

NS_ASSUME_NONNULL_BEGIN

@interface CHOperation : NSOperation

@property (nonatomic ,assign) CHOperationState state;

@property (nonatomic ,assign) NSInteger count;

@end

// MARK: CHOperation.m

#import "CHOperation.h"

@interface CHOperation ()

@property (nonatomic ,strong) NSRecursiveLock *lock;

@end

@implementation CHOperation

- (NSRecursiveLock *)lock {
    if (!_lock) {
        _lock = [[NSRecursiveLock alloc] init];
    }
    return _lock;
}

- (void)start {
    [self.lock lock];
    if (self.isCancelled) {
        [self operationDidCancel];
    } else if (self.isReady) {
        [self operationDidStart];
    }
    [self.lock unlock];
}

- (void)operationDidCancel {
    NSLog(@"count:%ld func:%s", self.count ,__FUNCTION__);
}

- (void)operationDidStart {
    NSLog(@"count:%ld func:%s", self.count ,__FUNCTION__);
    self.state = CHOperationStateFinish;
}

- (BOOL)isFinished {
    return self.state == CHOperationStateFinish;
}

- (BOOL)isConcurrent {
    return YES;
}

- (BOOL)isAsynchronous {
    return YES;
}

- (void)dealloc {

}

PS:有点偷懒,所以没写其余的状态.怎么写可以参考一下AFN3.0以下的自定义NSOperation.

AFN的例子是不管取消请求还是请求成功都算成了finish.按照AFN的讲就是如果执行完操作不是finish状态的话.NSOperation实例就不会销毁(不走dealloc).这点需要注意.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值