iOS开发

iOS开发 - GCD关闭后台子线程?

2017-10-16  本文已影响17人  阿唯不知道

iOS的GCD中如何关闭或者杀死一个还没执行完的后台线程?

本文主要是做一个笔记,感觉回答得非常👍,转自知乎的一个问答
iOS的GCD中如何关闭或者杀死一个还没执行完的后台线程?

知乎刘西浦解答 :

GCD本身是没有提供这样的API的。想要实现这样的功能需要自己在代码里实现:

@interface Canceller {
BOOL _shouldCancel;
    }
- (void)setShouldCancel:(BOOL)shouldCancel;
- (BOOL)shouldCancel;
@end

@implementation Canceller
- (void)setShouldCancel:(BOOL)shouldCancel {
    _shouldCancel = shouldCancel;
}
- (BOOL)shouldCancel {
    return _shouldCancel;
}
@end

static void test(int a){
    static Canceller * canceller = nil;

    if(q){
        [canceller setShouldCancel:YES];
        [canceller release];
        dispatch_suspend(q);
        dispatch_release(q);
        q=nil;
    }
    canceller = [[Canceller alloc] init];
    q=dispatch_get_global_queue(0,0);
    dispatch_async(q,^ {
        while(![canceller shouldCancel]){NSLog(@"query %d",a);sleep(2);}
    });
}

发布于 2014-05-27  
知乎Allen 赞同了该回答

嘿嘿嘿,去360面试被随口问了这么一个问题,貌似对他们来讲这是一个灰常简单的问题。我不会,面试官最后反问我:“如果我写一个return会怎样?”卧槽我就恍然大悟!return根执行到代码最后一样并没有什么区别。今天试验了一下,可行。比如这样:

BOOL gcdFlag = NO;

- (void)viewDidLoad {

    [super viewDidLoad];

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
      for (long i=0; i<100000; i++) {
           NSLog(@"i:%ld",i);
           sleep(1);
           if (gcdFlag==YES) {
             NSLog(@"收到gcd停止信号");
            return ;
         }
     };
        });


    dispatch_after(
    dispatch_time(DISPATCH_TIME_NOW,(int64_t)(15 * NSEC_PER_SEC)),
    dispatch_get_main_queue(), ^{
        NSLog(@"gcd停止信号发出!");
        gcdFlag = YES;
    });
}
上一篇下一篇

猜你喜欢

热点阅读