在一些技术型的企业里面,有关block面试笔试题,将会问得很深,如下例子:
请问DemoObj的对象能否正确释放,为什么?
//DemoObj.m @interface DemoObj() @property (nonatomic, strong) NSOperationQueue *queue; @end @implementation DemoObj - (instancetype)init { self = [super init]; if (self) { self.queue = [[NSOperationQueue alloc] init]; } return self; } - (void)dealloc { NSLog(@"demoobj dealloc"); } - (void)demoOp:(id)obj { NSLog(@"%@ %@", [NSThread currentThread], obj); } - (void)demoBlockOp { for (int i = 0; i < 10; ++i) { [self.queue addOperationWithBlock:^{ [self demoOp:@(i)]; }]; } } //SMViewController.m - (void)viewDidLoad { [super viewDidLoad]; DemoObj *obj = [[DemoObj alloc] init]; [obj demoBlockOp]; }
看过本人上一篇博文的读者可能会回答:DemoObj的对象不能被正确释放,原因是产生了循环引用啊。
但实际情况是,DemoObj的对象能被正确释放,读者不妨运行试试。
能被正确释放的原因是: 在并发编程中,block的管理以及线程的创建和销毁是由队列负责!当队列执行完被销毁时队列中得所有对象都会被销毁。
而循环引用只有在self直接强引用block才会出现。