美文网首页
自定义NSOperation的子类

自定义NSOperation的子类

作者: 7分醉 | 来源:发表于2016-03-04 15:05 被阅读538次

    在上一篇NSOperation简单使用中介绍了使用NSInvocationOperation和NSBlockOperation配合NSOperationQueue来实现多线程编程。
    这一篇来看一下通过自定义NSOperation的子类来实现多线程编程。

    创建SHOperation继承NSOperation

    #import <Foundation/Foundation.h>
    
    @interface SHOperation : NSOperation
    
    /**NSOperation的线程锁 */
    @property (readwrite, nonatomic, strong) NSRecursiveLock *lock;
    
    /**NSOperation的线程runloop模式 */
    @property (nonatomic, strong) NSSet *runLoopModes;
    
    @end
    
    #import "SHOperation.h"
    
    static NSString * const kMsspSDKLockName = @"operation.lock";
    
    @implementation SHOperation
    {
        BOOL finished;
        BOOL executing;
    }
    
    - (instancetype)init
    {
        self = [super init];
        if (!self)
        {
            return nil;
        }
        self.lock = [[NSRecursiveLock alloc] init];
        self.lock.name = kMsspSDKLockName;
        self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes];
        
        return self;
    }
    
    - (void)start
    {
        [self.lock lock];
        if ([self isCancelled])
        {
            [self willChangeValueForKey:@"isFinished"];
            finished = YES;
            [self didChangeValueForKey:@"isFinished"];
            return;
        }
        else if ([self isReady])
        {
            [self willChangeValueForKey:@"isFinished"];
            finished  = NO;
            [self didChangeValueForKey:@"isFinished"];
            
            [self willChangeValueForKey:@"isExecuting"];
            executing = YES;
            [self willChangeValueForKey:@"isExecuting"];
            
            NSLog(@"这里是start,线程号:%@", [NSThread currentThread]);
            //[self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO];
            [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
        }
        [self.lock unlock];
    }
    
    + (NSThread *)networkRequestThread
    {
        NSLog(@"networkRequestThread");
        static NSThread *_networkRequestThread = nil;
        static dispatch_once_t oncePredicate;
        dispatch_once(&oncePredicate, ^{
            _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];
            [_networkRequestThread start];
        });
        
        return _networkRequestThread;
    }
    
    + (void)networkRequestThreadEntryPoint:(id)__unused object {
        @autoreleasepool {
            NSLog(@"networkRequestThreadEntryPoint");
            [[NSThread currentThread] setName:@"TestThread"];
            NSRunLoop *runloop = [NSRunLoop currentRunLoop];
            [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
            [runloop run];
        }
    }
    
    - (void)operationDidStart
    {
        [self.lock lock];
        if (![self isCancelled])
        {
            NSLog(@"operationDidStart");
        }
        [self.lock unlock];
    }
    
    - (void)finishOperation
    {
        [self.lock lock];
        NSLog(@"is finishOperation");
        [self willChangeValueForKey:@"isExecuting"];
        executing = NO;
        [self didChangeValueForKey:@"isExecuting"];
        
        [self willChangeValueForKey:@"isFinished"];
        finished  = YES;
        [self didChangeValueForKey:@"isFinished"];
        [self.lock unlock];
    }
    
    - (BOOL) isConcurrent{
        NSLog(@"is concurrent");
        return YES;
    }
    
    - (BOOL) isFinished{
        NSLog(@"is finished");
        return finished;
    }
    
    - (BOOL) isExecuting{
        NSLog(@"is executing");
        return executing;
    }
    
    //- (void)cancel
    //{
    //    [self.lock lock];
    //    if (![self isFinished] && ![self isCancelled])
    //    {
    //        [super cancel];
    //    }
    //    [self.lock unlock];
    //}
    
    @end
    

    创建线程类,继承SHOperation类

    #import <Foundation/Foundation.h>
    #import "SHOperation.h"
    
    @interface T1Operation : SHOperation
    
    @end
    
    #import "T1Operation.h"
    
    @implementation T1Operation
    
    - (void)operationDidStart
    {
        [self.lock lock];
        if (![self isCancelled])
        {
            //需要在线程中运行的代码
            NSLog(@"T1   operationDidStart");
        }
        [self.lock unlock];
    }
    
    @end
    

    开启线程

    //创建队列
     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //创建操作
        T1Operation *t1 = [[T1Operation alloc] init];
    //将操作加入队列中
        [queue addOperation:t1];
    

    项目代码:github

    参考

    相关文章

      网友评论

          本文标题:自定义NSOperation的子类

          本文链接:https://www.haomeiwen.com/subject/kbhikttx.html