iOS后台调优后单例实例的生命周期

sna*_*ggs 2 objective-c ios swift

我有EventManagerReg例类(Obj-C):

事件管理器

class EventManager : NSObject {

   override init() {
     super.init()        

    Reg.shared().id = myId        
    Reg.shared().delegate = self
  }
}
Run Code Online (Sandbox Code Playgroud)

注册(单例)

@implementation Reg   

//...

+(Reg*) shared{
    static dispatch_once_t once;
    static Reg *manager;
    dispatch_once(&once, ^ { manager = [[Reg alloc] init]; });
    return manager;
}

//...
@end
Run Code Online (Sandbox Code Playgroud)

这是我在控制器中的调用:

class ViewController: UIViewController {

    let manager = EventManager()

    override func viewDidLoad() {
        super.viewDidLoad()        
        let a = SomeHandler.instance
    }

DispatchQueue.global(qos: .default).async {               

            SomeHandler.instance.registerBlocks({ obj in                
                let m = EventManager()                

            }, failureBlock: { (a, b, e) in                
                let m = EventManager()                

            }, status: { (a, b, c) in

            }) { value in                
                let m = EventManager()               
            }
}
Run Code Online (Sandbox Code Playgroud)

SomeHandler.instance.registerBlocks当设备进入后台并返回前台时,有时会在 10-15 秒后收到回调

我的问题是:Reg实例会发生什么?

如果应用程序始终处于活动状态,则每次调用时EventManager()我都应该获得相同的实例,Reg因为它是单例的。

但是,当设备进入后台操作系统时,会释放所有实例,因此当用户再次打开应用程序时Reg.shared()应该返回不同的实例,这是真的吗

如果实例Reg.shared()执行了一些长时间的工作(例如发送 HTTP 请求),会发生什么情况?

Ger*_*ero 5

要进一步详细说明 Paulw11 的评论,请参阅有关应用程序生命周期的文档。

很多人并没有真正具体说明“背景”的含义:

  1. 他们只需按下主页按钮,主屏幕或其他一些应用程序就会显示在屏幕上
  2. 刚刚设备进入睡眠状态
  3. 他们前段时间做了这件事
  4. 他们使用 Xcode 终止应用程序或重新启动设备,在任务管理器中看到该应用程序(双击主页按钮),因此他们假设它处于后台模式

“背景”的其他一些常见的不清楚用法也可能存在,但我想你会明白的。

正如 Paulw11 正确所说,您的单例将被释放的唯一时间是当应用程序进入“未运行”状态时,即它被终止。请注意,这种情况发生在我列出的情况 4 中,但是该应用程序是否列在任务管理器中并不表示它正在运行!我这么说是因为我遇到过有人说“我的应用程序刚刚进入后台,但是当我再次将其置于前台时,似乎我所有的启动代码都再次执行了!” 情况 3还可能最终导致您的应用程序被终止(即,它从“挂起”变为“不运行”),但不一定如此(取决于设备使用情况等)。前两种情况将导致应用程序首先进入后台模式(您的单例仍然存在),然后进入挂起模式(应用程序不再执行任何操作,但内存仍然完好无损,因此您的单例不会重新启动)稍后启动)。

最后,只有当应用程序终止时,(真正的)单例才会被释放,其他一切都将严重误用该术语(另请注意,这里存在单例的危险)。操作系统不会随机进入应用程序的内存分配并拿走其中的内容。它所做的唯一事情就是发送内存警告,让应用程序决定如何自行节省内存(如果它尚未挂起)。只有当这没有“控制”应用程序的资源使用内存时,“释放”应用程序:通过完全杀死它。

@Paulw11:我不想窃取你的答案,那么你为什么不从你的评论中做出一个呢?然后,snaggs 就可以接受这一点。:)