问题
I need to create a cache, that could save some objects, but then, at some point when I have memory warning or simply user wants it, I would like to purge all instances that are used only in the cache at the moment.
In other words: I need to deinit objects with ARC count == 1. The problem is that based on my googling of this project, it is not possible in pure Swift to get the retain count of an object.
From my experience I see that it is not possible by default in Swift. In objective-c I was using Proxy object, that was returned from cache, it had such overriden methods:
// Forward class checks for assertions.
-(BOOL)isKindOfClass:(Class)aClass {return [_target isKindOfClass:aClass];}
- (id)forwardingTargetForSelector:(SEL)aSelector
{
return(_target);
}
But is of course not applicable to Swift ideology.
One thought that I have is to base my cache on array of WeakBoxes, but this way unused objects will be deallocated when they become unused and that doesnt meet my requirements.
Can somebody guide me to some Swift possibilities, that I'm not aware of, to achieve such thing?
回答1:
You do not need to mess with the retain count of the object. Your cache can just hold a strong reference. This guarantees that the retain count is always at least one. When you get a memory warning you just loop through every pointer in the cache and set it to nil. Assuming no one else has a strong reference this decrements the reference count to zero and the object immediately calls deinit and goes out of memory. If you really really want the object to go out of memory when the cache does a purge, make sure only the cache has a strong reference to the items being held and that everyone else takes a weak reference. I have a lazily loaded array of ViewControllers that does something 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
}
}
}
来源:https://stackoverflow.com/questions/40227977/cache-that-can-purge-unused-objects-by-demand