自定义NSOperation的子类

2016-03-04  本文已影响538人  7分醉

在上一篇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

参考

上一篇下一篇

猜你喜欢

热点阅读