首页 > 代码库 > UIViewController生命周期控制

UIViewController生命周期控制

UIViewController生命周期控制

UIViewController介绍

官方的介绍如下

The UIViewController class provides the fundamental view-management model for all iOS apps. You rarely instantiate UIViewController objects directly. Instead, you instantiate subclasses of the UIViewController class based on the specific task each subclass performs.

简单的说就是一个视图控制器类

ios6以后的一般的生命周期

ios6以后取消了viewWillUnload方法,apple官方文档说没必要了(我勒个去了),大体就是view和显示分开了,当内存紧张的时候系统会帮你回收显示的贴图.这个贴图呢只是先标记为已经清除,如果你没用到这块内存,下次需要显示这个view的时候,还可以立马复用来.新的周期图大致如下.

在生命周期中, 给要做的事情分类

一千个人眼里有一千个哈姆雷特, 如果不统一下, 每个程序员按照自己的习惯的代码风格去写, 会给维护造成了困扰,所以我们给UIViewController的申明周期中加上一些方法来规范下

  • loadView 中加上三个方法

    • createFields 接受参数,初始化变量
    • createViews 创建视图
    • createEvents 绑定事件,如按钮的点击,NotificationCenter,kvo等
  • viewDidLoad

    • loadData 加载数据,调用一些api
  • dealloc

    • destroyEvents 取消事件的绑定
    • destroyViews 释放,销毁视图
    • destroyFields 释放,销毁引用的变量
  • didReceiveMemoryWarning

    • cleanData 释放一些可以释放的数据
  • 额外

    • enterForeground 进入前台时调用
    • enterBackground 进入后台时调用

规范文件内部组织结构

定义了运行时要做的事后,我们再来统一下文件内如何写

首先是头文件

@interface UIViewController (base)
#pragma mark- model
// 定义model

#pragma mark- view
// 定义view

#pragma mark- api
// 定义api
@end

实现文件

#pragma mark - api
// 对外的接口

#pragma mark - rewrite
// 额外的重写的父类的方法

#pragma mark - private

#pragma mark - 响应 model 的地方
#pragma mark 1 notification
#pragma mark 2 KVO

#pragma mark - 响应 view 的地方
#pragma mark 1 target-action
#pragma mark 2 delegate dataSource protocol

#pragma mark -

结束

至此呢,我们的UIViewController就有了一个统一的风格,在团队的扩建中,再统一下命名,代码看起来就舒服多了

实现代码

实现可以用runtime,也可以用基类, 个人推荐是用基类,但是下面的代码是runtime的

@implementation UIViewController (base)

+ (void)load
{
    XY_swizzleInstanceMethod([UIViewController class], @selector(loadView), @selector(xy__loadView));
    XY_swizzleInstanceMethod([UIViewController class], @selector(viewDidLoad), @selector(xy__viewDidLoad));
    XY_swizzleInstanceMethod([UIViewController class], NSSelectorFromString(@"dealloc"), @selector(xy__dealloc));
    XY_swizzleInstanceMethod([UIViewController class], @selector(didReceiveMemoryWarning), @selector(xy__didReceiveMemoryWarning));
}

- (void)xy__loadView
{
    [self xy__loadView];

    if ([self respondsToSelector:@selector(createFields)])
        [self performSelector:@selector(createFields)];

    if ([self respondsToSelector:@selector(createViews)])
        [self performSelector:@selector(createViews)];

    if ([self respondsToSelector:@selector(enterBackground)])
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
    }

    if ([self respondsToSelector:@selector(enterForeground)])
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
    }

    if ([self respondsToSelector:@selector(createEvents)])
        [self performSelector:@selector(createEvents)];
}

- (void)xy__dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    if ([self respondsToSelector:@selector(destroyEvents)])
        [self performSelector:@selector(destroyEvents)];

    if ([self respondsToSelector:@selector(destroyViews)])
        [self performSelector:@selector(destroyViews)];

    if ([self respondsToSelector:@selector(destroyFields)])
        [self performSelector:@selector(destroyFields)];

    [self xy__dealloc];
}

- (void)xy__viewDidLoad
{
    if ([self respondsToSelector:@selector(loadData)])
        [self performSelector:@selector(loadData)];

    [self xy__viewDidLoad];
}

- (void)xy__didReceiveMemoryWarning
{
    if ([self isViewLoaded] && [self.view window] == nil)
    {
        if ([self respondsToSelector:@selector(cleanData)])
            [self performSelector:@selector(cleanData)];
    }

    [self xy__didReceiveMemoryWarning];
}

@end

UIViewController生命周期控制