为何该Objective-C单例可行?局部静态实例的生命周期与存储疑问
Objective-C单例静态变量的常见疑问解答
好问题!咱们一步步拆解你关心的这几个点:
1. 持有者释放后,静态变量AdManager *manager会被释放吗?
完全不会。这个静态变量虽然定义在sharedInstance方法的作用域里,但它的生命周期是和整个应用程序绑定的,根本不依赖任何持有者对象。哪怕所有持有这个单例实例的其他对象都被销毁了,这个静态变量对实例的强引用(默认情况下)会一直让实例保持存活状态,直到应用进程完全终止才会被清理。
2. 方法作用域里的静态变量和成员变量有啥区别?会不会被释放?
方法内的静态变量和类的成员变量(不管是实例成员还是类成员)的核心差异在存储位置和生命周期:
- 实例成员变量:属于单个对象实例,实例销毁时它也跟着被释放;
- 类成员变量:属于类本身,生命周期和应用一致;
- 方法作用域的静态变量:虽然定义在方法代码块里,但它存放在全局静态存储区,从第一次被初始化开始,就会一直存在到应用退出。哪怕方法执行完毕,这个变量也不会被销毁,下次调用方法时还能直接访问到它。
所以你不用担心它会被提前释放——它的存活周期和应用一样长。
3. 这个对象存储在哪里,下次调用sharedInstance还能用到?
单例实例本身的内存是分配在堆区的(毕竟Objective-C的对象都是在堆上创建的),而指向它的静态变量manager则存在全局静态存储区。当你第一次调用sharedInstance时,静态变量会被初始化,指向堆上新建的单例实例;之后每次调用这个方法,都会直接返回静态变量里保存的指针,自然就能拿到之前创建好的那个实例了。
顺便提个线程安全的小细节:标准的Objective-C单例实现一般会用dispatch_once来保证只初始化一次,比如:
+ (instancetype)sharedInstance { static AdManager *manager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ manager = [[self alloc] init]; }); return manager; }
这里的manager和onceToken都是全局静态存储区的变量,所以不管多少线程同时调用,都只会创建一次实例。
内容的提问来源于stack exchange,提问作者armnotstrong
相关产品推荐
相关产品推荐

