DEViewControllerCache 0.1

DEViewControllerCache 0.1

测试测试
语言语言 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 实例。

访问 UIViewControllers

要检索一个 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 分类

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