Dealloc 在哪个线程执行

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的线程被调用.

 
时间: 2024-10-24 16:07:05

Dealloc 在哪个线程执行的相关文章

java主线程等待所有子线程执行完毕在执行(常见面试题)

java主线程等待所有子线程执行完毕在执行(常见面试题) java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用户下单成功,下面就说一下我能想到的方法,欢迎大家批评指正: 用sleep方法,让主线程睡眠一段时间,当然这个睡眠时间是主观的时间,是我们自己定的,这个方法不推荐,但是在这里还是写一下,毕竟是解决方法 2.使用Thread的join()等待所有

python之多线程执行和非线程执行的对比

一.非线程执行(普通的执行) 1.非线程运行,简单代码如下 #_*_coding:utf-8_*_ import time import threading a = [] b = [] def func1():     print "func1 start %s" % time.ctime()     alist = ["192.168.1.100","192.168.1.120","192.168.1.134","

DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码: 下面的是dll模块的的, dll的工程文件: [delphi] view plaincopy library DllAPP; uses windows, SysUtils, Classes, DllClass in 'DllClass.pas'; {$R *.res} var GDllServer: TDllServer; functio

Java多线程--让主线程等待所有子线程执行完毕

数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis()在最后一个子进程结束后记录当前时间,两次一减得到的时间差即为总共的用时,代码如下 Java代码   long tStart = System.currentTimeMillis(); System.out.println(Thread.currentThread().getName() + "开始&

Java线程池主线程等待子线程执行完成

今天讨论一个入门级的话题, 不然没东西更新对不起空间和域名~~ 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线程的流程,  往往需要让主线程指定后, 等待子线程的完成. 这里有几种方式. 站在 主线程的角度, 我们可以分为主动式和被动式. 主动式指主线主动去检测某个标志位, 判断子线程是否已经完成. 被动式指主线程被动的等待子线程的结束, 很明

线程间操作无效: 从不是创建控件“控件id”的线程访问它。(.net跨线程执行方法)

找了好久资料,终于解决了,特此记录下来. 1 delegate void DelListHandler(string number); /// <summary> /// 按标识删除listview内容 /// </summary> /// <param name="number">标识</param> private void DelListViewLog(string number) { for (int i = 0; i <

Java多线程系列四——控制线程执行顺序

假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatch类:指定计数器,当计数器清零即取消阻塞 import java.util.concurrent.CountDownLatch; import org.junit.Assert; import org.junit.Test; /** * @Description: 规定线程次序的方法 */ publ

Java多线程、主线程等待所有子线程执行完毕、共享资源

1.Java创建与启动线程 Java提供两种方式创建和启动线程:1.直接Thread类,2.实现Runable接口. 1.1  继承Thread类 public class myThread extends Thread { public void run(){ for(int i=0;i<5;i++){ System.out.println(this.getName()+":"+i); } } public static void main(String[] args){ //

java中线程存活和线程执行的问题!

1 /* 2 下面的程序会出现下面的情况,当Thread-0, Thread-1, Thread-2都被wait的时候,可能会同时苏醒 3 Thread-0 put 4 Thread-1 put 5 Thread-2 put 6 Thread-3 get//在此处,Thread-3拿到锁之后,将所有的等待的线程唤醒,才有了下面的输出 7 Thread-2 put 8 Thread-1 put 9 Thread-0 put 10 */ 11 12 13 虽然多个线程会同时苏醒,但是只有一个能获得c