Concurrency5

一、Running Tasks Synchronously with Operations

1.说明
当你想要运行一系列的同步任务的时候,你可以创建operations来启动它。
eg: 看如下代码

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) NSInvocationOperation *simpleOperation;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void) simpleOperationEntry:(id)paramObject{
    NSLog(@"Parameter Object = %@", paramObject);
    NSLog(@"Main Thread = %@", [NSThread mainThread]);
    NSLog(@"Current Thread = %@", [NSThread currentThread]);
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSNumber *simpleObject = [NSNumber numberWithInteger:123];
    self.simpleOperation = [[NSInvocationOperation alloc]
                            initWithTarget:self
                            selector:@selector(simpleOperationEntry:) object:simpleObject];
    [self.simpleOperation start];
}
@end

运行结果:
2016-01-20 17:52:34.098 ConcurrencyDemo_01[14251:4625160] Parameter Object = 123
2016-01-20 17:52:34.098 ConcurrencyDemo_01[14251:4625160] Main Thread = {number = 1, name = main}
2016-01-20 17:52:34.099 ConcurrencyDemo_01[14251:4625160] Current Thread = {number = 1, name = main}

正如其名称的意思,这个方法的主要功能就是调用一个对象的内部方法。这是利用operations的最简单的一种方式。

一个调度操作,可以调用一个对象内的方法。你或许会发出“这又有什么特别的地方呢?”的疑问。调度队列的巨大能量在于当它被添加到操作队列中时。与操作队列相比,一个调用操作可以调用在一个目标对象的方法和异步平行于启动该操作的线程。如果你注意到控制台的输出,你会发现当前线程就是主线程。

除了调用操作,你可以利用block或者plain 操作去执行同步的任务。下面是一个利用block operation来计算从0到999的和。

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic,strong) NSBlockOperation *simpleOperation;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.simpleOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"Main Thread = %@",[NSThread mainThread]);
        NSLog(@"Current Thread = %@",[NSThread currentThread]);
        NSUInteger counter = 0;
        for (counter = 0; counter < 1000; counter++) {
            NSLog(@"Count = %lu",(unsigned long)counter);
        }
    }];
    [self.simpleOperation start];

    /* Print something out just to test if we have to wait for the block to execute its code or not */
    NSLog(@"Main thread is here");
}
@end

运行结果:
2016-01-20 18:36:02.789 ConcurrencyDemo_01[17767:4666065] Main Thread = {number = 1, name = main}
2016-01-20 18:36:02.790 ConcurrencyDemo_01[17767:4666065] Current Thread = {number = 1, name = main}
2016-01-20 18:36:02.790 ConcurrencyDemo_01[17767:4666065] Count = 0
…………
2016-01-20 18:36:03.020 ConcurrencyDemo_01[17767:4666065] Main thread is here

这证明了自从block operation启动开始,它本身就运行在主线程上,在block中的代码自然也运行在主线程上。最重要的一点是当当operation blocked the main thead and the main thread’s code continued to be executed after the work for the block operation was done.这是非常糟糕的。ios开发这应该确保主线程尽量少的耗时任务,尽量的轻。

除了invocation operations 和 block operations ,你还可以自己继承NSOperation类来实现你自己的任务。当你继承NSOperation的时候,有以下注意事项:
- If you are not planning on using an operation queue, you have to detach a new thread of your own in the start method of the operation. If you do not want to use an operation queue and you do not want your operation to run asynchronously from other operations that you start manually, you can simply call the main method of your operation inside the start method.
- TwoimportantmethodsinaninstanceofNSOperationmustbeoverriddenbyyour own implementation of the operation: isExecuting and isFinished. These can be called from any other object. In these methods, you must return a thread-safe value that you can manipulate from inside the operation. As soon as your operation starts, you must, through KVO, inform any listeners that you are changing the values that these two methods return. We will see how this works in the example code.
- You must provide your own autoreleasepool inside the main method of the operation in case your operation will be added to an operation queue at some point in the future. You must make sure your operations work in both ways: whether you start them manually or they get started by an operation queue.
- You must have an initialization method for your operations. There must be only one designated initializer method per operation. All other initializer methods, in‐ cluding the default init method of an operation, must call the designated initializer that has the greatest number of parameters. Other initializer methods must make sure they pass appropriate parameters (if any) to the designated initializer.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值