测试测试 | ✗ |
语言语言 | Obj-CObjective C |
许可证 | MIT |
版本最后发布 | 2014年12月 |
由Dream Engine维护。
依赖项 | |
DECategories/UIViewController+DEConveniences | >= 0 |
OSCache | >= 0 |
https://github.com/dreamengine/DEViewControllerCache
DEViewControllerCache
是一个 MIT 许可的缓存系统,可以让 UIViewControllers
可重用。它在缓存中没有可回收的对象时自动实例化新的控制器实例(类似于从 UITableViews
中的 -dequeueReusableCellWithIdentifier:
)。它还会在发生内存警告时自动从内存中删除未使用的控制器。通过减少实例化事件,您的应用程序变得更快,响应更灵敏。
如果以下任何一项为真,则认为一个 UIViewController
实例当前处于 正在使用 状态:
否则,一个视图控制器实例被认为当前是 未使用 或 未用的。
如果一个 UIViewController
实例满足以下两个条件,则称它正在为重用 做准备:
-controllerForControllerClass:
返回)。DEViewControllerCache
随带一个默认的静态实例。可以使用 +defaultCache
访问它。对于每一个实例方法,都有一个等效的类方法供方便调用(例如调用 +controllerForClass:
与调用 [[DEViewControllerCache defaultCache] controllerForClass:]
等效)。
如果有更复杂的缓存方案,您可以简单地忽略这个单例,并创建多个 DEViewControllerCache
实例。
要检索一个 UIViewController
子类的实例,请使用 -controllerForClass:
方法,并传入子类的 Class
作为参数。
如果实例已在缓存中并且当前未被使用,则返回该实例,并且被视为可重用。否则,没有可用的实例,因此将自动实例化一个新的视图控制器对象(见下文 自动实例化)。
如果 -controllerForClass:
将返回一个可重用实例,并且如果视图控制器实例可以响应该选择器,它将首先在该视图控制器实例上调用 -willBeReused
方法。 (见下文 UIViewController 分类)
期望从 -controllerForClass:
返回的控制器将立即设置,以便它们被视为在使用中。否则,在用相同的类再次调用 -controllerForClass:
时可能会返回相同的实例。
一旦控制器实例不再需要,则应将其更新,以便被视为未被使用。如果您的应用程序遵循正常的用户界面生命周期(例如在导航堆栈中推送/弹出控制器),则不应使用状态应自动发生。
#import "MyViewController.h"
@implementation MenuController
-(IBAction)buttonTapped {
MyViewController *controller = [DEViewControllerCache controllerForClass:MyViewController.class];
// customize/provide data to the controller as necessary
controller.date = [NSDate date];
[self.navigationController pushViewController:controller animated:YES];
}
@end
DEViewControllerCache
将自动实例化一个控制器,如果缓存中还没有这个子类的对象。为了实现这一点,DEViewControllerCache
需要该 UIViewController
子类使用一个与文件名匹配的 nib(例如,MyCustomViewController.xib 用于 MyCustomViewController)或者该子类具有使用编程定义的用户界面(即没有任何 nib)。这是通过使用 DECategories/UIViewController+DEConveniences
实现的。
当 UIViewController
实例将要被重用时,有时在再次向用户显示之前清理实例可能是有意义的。例如,如果一个登录控制器实例中已经有之前填写过的用户名和密码 UITextFields
,应该在再次显示控制器之前先清除这些字段。
要使用这个功能,只需为您的控制器添加一个方法 -willBeReused
并在其中执行任何必要的清理操作。当重用的控制器即将通过 -controllerForClass:
返回时,DEViewControllerCache
将会调用该方法。
请注意,当控制器首次被实例化和从 -controllerForClass:
返回时,不会调用 -willBeReused
。它只会在控制器将要第二次或以后返回时调用 -controllerForClass:
。
此外,请注意,-willBeReused
是一个可选方法,因此 DEViewControllerCache
不要求缓存的控制器有这个方法。
@implementation MyLoginViewController
-(void)willBeReused {
// not necessary to call super if your controller is a direct subclass of UIViewController,
// but could be useful if you have deeper inheritance chains
[super willBeReused];
self.usernameField.text = @"";
self.passwordField.text = @"";
self.usernameField.enabled = YES;
self.passwordField.enabled = YES;
}
@end
可能存在一些情况,您的应用程序需要手动从缓存中删除条目以减少总体内存开销。DEViewControllerCache
提供了手动缓存管理的三个层级。
第一个层级是实例特定的。从缓存中移除特定实例,请使用 -removeControllerFromCache:
。
第二个层级是类特定的。从缓存中移除特定 UIViewController
子类的所有实例,请使用 -removeClassInstancesFromCache:
。
第三个层级是缓存特定的。从缓存中移除所有 UIViewController
子类的所有实例,请使用 -removeAllClassInstancesFromCache
。
#import "MyViewController.h"
@interface MenuController ()
@property (strong, nonatomic) MyViewController *myViewController;
@end
@implementation MenuController
-(void)someMethod {
// remove a controller instance from the cache
[DEViewControllerCache removeControllerFromCache:self.myViewController];
// remove all controller instances of a class from the cache
[DEViewControllerCache removeClassInstancesFromCache:MyViewController.class];
// remove all controller instances of all classes from the cache
[DEViewControllerCache removeAllClassInstancesFromCache];
}
@end