Dealloc 在哪个线程执行

时间:2024-12-25 11:04:08

1. 引子

在面试过程中曾见过这样一道笔试题,选择你认为对的答案

A.所有对象的dealloc方法会在主线程调用

B.一个对象的dealloc方法会在分配该对象的线程被调用

C.一个对象的dealloc方法会在该对象的引用计数变为0的线程被调用

D.手动调用的当前线程中

当时对此题没有明确的答案,回去便开始查阅资料寻找答案。

2.dealloc

对象在经历其生命周期后,最终会为系统所回收,这时就会调用dealloc方法了。在每个对象的生命周期内,此方法仅执行一次,也就是当保留计数降为0的时候。然而具体何时执行,则无法保证。可以简单的理解为:“你绝不应该自己调用dealloc方法,runtime机制会在适当的时候调用他。”这样D答案可以排除。

在看A答案和B答案,我们可以假设如果对象实在主线程中创建在其他线程中被移除,该对象的dealloc应该在主线程中被调用吗?有了这样的假设就应该去小心的验证了,下面给出一段简单的代码。

#import "ViewController.h"

@interface ClassA : NSObject
@end @implementation ClassA - (void)dealloc
{
NSLog(@"dealloc is excuted in thread : %@, object : %@", [NSThread currentThread], self);
} @end
@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *array;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. _array = [NSMutableArray array];
ClassA *objectA = [[ClassA alloc] init];
NSLog(@"Thread: %@, object : %@", [NSThread currentThread],objectA);
[_array addObject:objectA]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[NSThread currentThread] setName:@"DISPATCH_QUEUE_Thread_Custom"];
[_array removeAllObjects];
});
}
@end

运行得到的输出为

2015-10-07 12:17:46.753 测试[1741:53054] Thread: <NSThread: 0x7ff223411940>{number = 1, name = main}, object : <ClassA:        0x7ff223546510>

2015-10-07 12:17:46.754 测试[1741:53110] dealloc is excuted in thread : <NSThread: 0x7ff223708ec0>{number = 2, name = DISPATCH_QUEUE_Thread_Custom}, object : <ClassA: 0x7ff223546510>

3.结论

可见, objectA 的分配是在主线程, 然后用一个数组来强引用到该对象, 并在一个dispatch_queue里清空数组,以达到释放 objectA的目的,输出的结果表明答案应该选

  C: 一个对象的dealloc方法会在该对象的引用计数变为0的线程被调用.