swift - basics - Caché que puede purgar objetos no utilizados por demanda
swift variables (1)
Necesito crear un caché, que podría salvar algunos objetos, pero luego, en algún momento cuando tengo una advertencia de memoria o simplemente el usuario lo quiere, me gustaría purgar todas las instancias que se usan solo en el caché en este momento.
En otras palabras: necesito definir objetos con recuento de ARC == 1. El problema es que, basado en mi búsqueda en Google de este proyecto, no es posible en Swift puro obtener el conteo retenido de un objeto.
Desde mi experiencia, veo que no es posible por defecto en Swift. En Object-C estaba usando el objeto Proxy, que se devolvió de la memoria caché, tenía tales métodos anulados:
// Forward class checks for assertions.
-(BOOL)isKindOfClass:(Class)aClass {return [_target isKindOfClass:aClass];}
- (id)forwardingTargetForSelector:(SEL)aSelector
{
return(_target);
}
Pero, por supuesto, no es aplicable a la ideología de Swift.
Un pensamiento que tengo es basar mi caché en una matriz de WeakBoxes, pero de esta manera los objetos no utilizados serán desasignados cuando no se usen y eso no cumple con mis requisitos.
¿Puede alguien guiarme a algunas posibilidades de Swift, que no conozco, para lograr tal cosa?
No necesita meterse con el conteo retenido del objeto. Tu caché solo puede contener una referencia fuerte. Esto garantiza que el conteo de retención sea siempre al menos uno. Cuando aparece una advertencia de memoria, simplemente recorre todos los punteros del caché y lo establece en cero. Suponiendo que nadie más tenga una referencia fuerte, esto disminuye la cuenta de referencia a cero y el objeto llama inmediatamente a deinit y se queda sin memoria. Si realmente desea que el objeto se quede sin memoria cuando la caché realiza una purga, asegúrese de que solo la memoria caché haga una referencia fuerte a los elementos retenidos y que todos los demás tomen una referencia débil. Tengo una matriz de ViewControllers cargados de forma laxa que hace algo similar:
fileprivate var controllers = [UIViewController?](repeating: nil, count: DashboardInfo.Category.allValues.count)
override func didReceiveMemoryWarning() {
//Release every off screen controller
for index in 0 ..< controllers.count {
if controllers[index] != currentController {
controllers[index]?.removeFromParentViewController()
controllers[index]?.view.removeFromSuperview()
controllers[index] = nil
}
}
}