主要是针对最近校招,面试官提的一些问题的总结与思考。
首先是关于GCD的,就是如何实现取消正在下载执行的任务,首先看一个Demo:
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t queue = dispatch_queue_create("CONCURRENT", DISPATCH_QUEUE_CONCURRENT);
// 第一个线程
dispatch_async(queue, ^{
for (int i = 0; i < 10000; i++) {
if (_isCaceled) {
NSLog(@"%@ ",[NSThread currentThread]);
// [NSThread exit];
break;
}
NSLog(@"%@ i = %d",[NSThread currentThread],i);
}
});
// 第二个线程
dispatch_async(queue, ^{
for (int i = 0; i < 10000; i++) {
NSLog(@"%@ j = %d",[NSThread currentThread],i);
}
});
NSLog(@"---end---");
第一点要理解的是,如果是dispatch_async()来执行异步任务它是不会阻塞当前函数的执行,而使用dispatch_sync()则会;那么该如何取消正在执行的操作呢?我在网上查了很多资料,发现并没有很好的解决取消下载的办法,目前我想到一个办法就是在执行的代码块中,用一个死循环设置一个标记变量,不断判断是否取消线程执行,如果接收到取消执行,那么直接return就可以保证block任务的取消,但这并不能保证网络任务也会取消。
其次是关于NSOperation的,也同样的看Demo,
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
for (int i = 0; i < 1000; i++) {
if (i == 500) {
[blockOperation1 cancel];
return ;
}
NSLog(@"i = %d",i);
}
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
for (int i = 0; i < 1000; i++) {
NSLog(@"j = %d",i);
}
}];
// [blockOperation start];// 直接调用将会同步执行
// [queue addOperation:blockOperation1];// 添加到队列异步执行
[blockOperation1 addDependency:blockOperation2];// 添加依赖关系,前一个任务依赖后一个任务的执行
[queue addOperation:blockOperation1];
[queue addOperation:blockOperation2];
// [blockOperation2 start];
// [blockOperation1 start];// 调用会出现错误
NSLog(@"---end---");
下载任务的取消也同样的是参照上面GCD的解决办法,但也并不是很有效;需要说明的是,当设置NSOperation任务的依赖关系时,从属的任务不能调用start方法,否则会报错。