NSOperation
NSOperation的作用
- 配合使用NSOperation和NSOperationQueue也能实现多线程编程
使用NSOperation子类的方式有3种
- NSInvocationOperation
- NSBlockOperation
- 自定义子类继承NSOperation,实现内部相应的方法
NSInvocationOperation
- 注意
- 默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作
- 只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作
- (void)test2
{
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(print:) object:@"hello"];
[op start];
}
log
-NSOperationQueue[1600:268010] ----------print,hello
-NSOperationQueue[1600:268010] <NSThread: 0x7fb380f00ac0>{number = 1, name = main}
- (void)test2
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(print:) object:@"hello"];
[queue addOperation:op];
}
- (void)print:(NSString *)argv
{
NSLog(@"----------print,%@",argv);
NSLog(@"%@",[NSThread currentThread]);
}
log 打印
掌握-NSOperationQueue[1614:271415] ----------print,hello
掌握-NSOperationQueue[1614:271415] <NSThread: 0x7fc610e78a90>{number = 2, name = (null)}
NSBlockOperation
+ (id)blockOperationWithBlock:(void (^)(void))block;
- (void)addExecutionBlock:(void (^)(void))block;
- 注意:只要NSBlockOperation封装的操作数 > 1,就会异步执行操作
- (void)test3
{
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"----------NSBlockOperation1");
NSLog(@"%@",[NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"----------NSBlockOperation2");
NSLog(@"%@",[NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"----------NSBlockOperation3");
NSLog(@"%@",[NSThread currentThread]);
}];
[op start];
log 打印
掌握-NSOperationQueue[1651:279652] ----------NSBlockOperation1
掌握-NSOperationQueue[1651:279652] <NSThread: 0x7fcae3505d60>{number = 1, name = main}
掌握-NSOperationQueue[1651:279706] ----------NSBlockOperation2
掌握-NSOperationQueue[1651:279713] ----------NSBlockOperation3
掌握-NSOperationQueue[1651:279706] <NSThread: 0x7fcae360c250>{number = 2, name = (null)}
掌握-NSOperationQueue[1651:279713] <NSThread: 0x7fcae3712400>{number = 3, name = (null)}
}
NSOperationQueue
- NSOperation可以调用start方法来执行任务,但默认是同步执行的
- 如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作
添加操作到NSOperationQueue中
- (void)addOperation:(NSOperation *)op;
- (void)addOperationWithBlock:(void (^)(void))block;
最大并发数
- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
- (void)test1
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
NSLog(@"----------NSBlockOperation1");
NSLog(@"%@",[NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"----------NSBlockOperation2");
NSLog(@"%@",[NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"----------NSBlockOperation3");
NSLog(@"%@",[NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"----------NSBlockOperation4");
NSLog(@"%@",[NSThread currentThread]);
}];
log 打印
-NSOperationQueue[1666:287432] ----------NSBlockOperation1
-NSOperationQueue[1666:287432] <NSThread: 0x7fba515134b0>{number = 2, name = (null)}
-NSOperationQueue[1666:287432] ----------NSBlockOperation2
-NSOperationQueue[1666:287432] <NSThread: 0x7fba515134b0>{number = 2, name = (null)}
-NSOperationQueue[1666:287432] ----------NSBlockOperation3
-NSOperationQueue[1666:287432] <NSThread: 0x7fba515134b0>{number = 2, name = (null)}
-NSOperationQueue[1666:287432] ----------NSBlockOperation4
-NSOperationQueue[1666:287432] <NSThread: 0x7fba515134b0>{number = 2, name = (null)}
}
队列的取消、暂停、恢复
- (void)cancelAllOperations;
提示:也可以调用NSOperation的- (void)cancel方法取消单个操作
- (void)setSuspended:(BOOL)b;
- (BOOL)isSuspended;
操作的监听
- (void (^)(void))completionBlock;
- (void)setCompletionBlock:(void (^)(void))block;
- (void)test2
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(print:) object:@"hello"];
[op setCompletionBlock:^{
NSLog(@"完了");
}];
[queue addOperation:op];
}
- (void)print:(NSString *)argv
{
NSLog(@"----------print,%@",argv);
NSLog(@"%@",[NSThread currentThread]);
}
log 打印
掌握-NSOperationQueue[1680:294419] ---------- print,hello
掌握-NSOperationQueue[1680:294419] <NSThread: 0x7fd37942f640>{number = 2, name = (null)}
掌握-NSOperationQueue[1680:294423] 完了
操作依赖
- NSOperation之间可以设置依赖来保证执行顺序
- 比如一定要让操作A执行完后,才能执行操作B,可以这么写[operationB addDependency:operationA]; // 操作B依赖于操作A
- 可以在不同queue的NSOperation之间创建依赖关系
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download1----%@", [NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download2----%@", [NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download3----%@", [NSThread currentThread]);
}];
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
for (NSInteger i = 0; i<10; i++) {
NSLog(@"download4----%@", [NSThread currentThread]);
}
}];
NSBlockOperation *op5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download5----%@", [NSThread currentThread]);
}];
op5.completionBlock = ^{
NSLog(@"op5执行完毕---%@", [NSThread currentThread]);
};
[op3 addDependency:op1];
[op3 addDependency:op2];
[op3 addDependency:op4];
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[queue addOperation:op4];
[queue addOperation:op5];
}
log 打印
2016-07-07 16:35:45.260 04-掌握-操作依赖[1715:299708] download1----<NSThread: 0x7f9f61e1c040>{number = 2, name = (null)}
2016-07-07 16:35:45.260 04-掌握-操作依赖[1715:299697] download2----<NSThread: 0x7f9f61f0ec20>{number = 3, name = (null)}
2016-07-07 16:35:45.260 04-掌握-操作依赖[1715:299747] download5----<NSThread: 0x7f9f61c1a990>{number = 4, name = (null)}
2016-07-07 16:35:45.260 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.261 04-掌握-操作依赖[1715:299747] op5执行完毕---<NSThread: 0x7f9f61c1a990>{number = 4, name = (null)}
2016-07-07 16:35:45.261 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.261 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.262 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.262 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.262 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.262 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.262 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.263 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.303 04-掌握-操作依赖[1715:299706] download4----<NSThread: 0x7f9f61f13fb0>{number = 5, name = (null)}
2016-07-07 16:35:45.303 04-掌握-操作依赖[1715:299708] download3----<NSThread: 0x7f9f61e1c040>{number = 2, name = (null)}