我的 (iOS7/ARC) 应用程序具有“登录”的概念,用户可以在其中连接到远程服务器。在用户登录 session 期间,我有一些单例对象来处理低级方面(套接字、处理传入消息等)。当用户注销时,我想处理这些单例,然后在用户重新登录时重新创建它们(假设应用程序没有消失或退出)。
单例是这样创建的:
static MYChatMessageManager *messageManager = nil;
static dispatch_once_t onceToken = 0;
+(MYChatMessageManager *) messageManager
{
dispatch_once(&onceToken, ^{
messageManager = [[self alloc] init];
// Do any other initialisation stuff here
});
return messageManager;
}
然后我定义了一个我认为可以完成任务的类方法
+(void) shutdown
{
onceToken = 0;
messageManager = nil;
}
当我调用它时,我希望调用单例实例的 -dealloc
方法,因为 ARC 应该看到没有人引用它。但是,-dealloc
没有被调用,在调试器中,在调用 +shutdown
之后,我停止了应用程序(shutdown
已经运行并且迟了几秒钟,我只是停止了应用程序)并检查了 messageManager 内存位置的对象(之前从 lldb 获取,而不是在代码中),它的 retainCount
仍然为 1。我可以识别在我的应用程序中没有任何地方可以为任何变量或对象指针分配此对象,这会通过 ARC 增加保留计数。
我不确定我能做些什么来让这个单例消失。
最佳答案
使用 Allocations Instrument,打开引用事件跟踪,然后查看持有最终引用的内容。
你做过的,或多或少(至少找到了最后一个引用)。
但是,这是糟糕的设计,代码也有问题。首先,如评论中所述,无法重置 dispatch_once_t
。
其次,也是更大的问题,您应该永远不要销毁共享实例,并且暗示类的 -dealloc
方法中不应该有关键逻辑(这, 顺便说一句,它更像是一条通用规则,而不是特定于共享实例类的规则。
根据“共享实例”的定义,该对象应该永远存在。如果它需要在“事件”和“关闭”状态之间转换,则以不将其与对象的生命周期联系起来的方式添加该逻辑。
关于ios - ObjC 如何在应用程序未退出时处理单例对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23962292/