UIViewController Lifecycle

作为每个初学者99.9%会接触到的UIViewController,这篇文章主要来讲讲UIViewController的生命周期。

我们从一个例子来证明这个结论:

如下是storyBoard的配置:

ViewController.m

@interface ViewController ()
@property (nonatomic,strong)NSString *str;
@property (weak, nonatomic) IBOutlet UIButton *button;
@end

下面是生命周期有关的方法:

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        NSLog(@"0");
    }
    return self;
}

-(void)awakeFromNib{
    NSLog(@"1");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"2");
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    NSLog(@"3");
}

-(void)viewWillLayoutSubviews{
    NSLog(@"4");
}

-(void)viewDidLayoutSubviews{
    NSLog(@"5");
}

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    NSLog(@"6");
}

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    NSLog(@"7");
}

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    NSLog(@"8");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

运行后点击按钮跳转到第二个控制器,打印如下:

2015-03-24 00:00:44.771 test[2925:305854] 0
2015-03-24 00:00:44.772 test[2925:305854] 1
2015-03-24 00:00:44.778 test[2925:305854] 2
2015-03-24 00:00:44.779 test[2925:305854] 3
2015-03-24 00:00:44.785 test[2925:305854] 4
2015-03-24 00:00:44.785 test[2925:305854] 5
2015-03-24 00:00:44.788 test[2925:305854] 6
2015-03-24 00:00:47.982 test[2925:305854] 7
2015-03-24 00:00:47.987 test[2925:305854] 4
2015-03-24 00:00:47.988 test[2925:305854] 5
2015-03-24 00:00:48.489 test[2925:305854] 8

也就是说,ViewController的生命周期基本是下面的步骤:

Instantiated :初始化
awakeFromNib:主要做一些viewDidLoad之前的事情
outlets 的配置
viewDidLoad
viewWillLayoutSubviews和viewDidLayoutSubviews:
viewWillAppear和viewDidAppear
viewWillDisappear: and viewDidDisappear
didReceiveMemoryWarning:收到内存警告
现在不存在“unload”方法

你可能会问为什么outlets 的配置介于awakeFromNib和viewDidLoad之间呢,我们可以通过下面的代码证实一下:

-(void)awakeFromNib{
    NSLog(@"1");
    [_button setTitle:@"哈哈" forState:UIControlStateNormal];
}

运行结果发现按钮的标题并没有发生变化,我们再看:

- (void)viewDidLoad {
    [super viewDidLoad];
    [_button setTitle:@"呵呵" forState:UIControlStateNormal];
    NSLog(@"2");
}

运行结果发现按钮的标题发生变化了,所以可以知道outlets 的配置是介于awakeFromNib和viewDidLoad,这点比较重要。

1.initWithCoder ,
关于initWithCoder ,你是不是觉得它更应该出现在数据持久化中呢?确实它是一个NSCoding protocol, 所以你在UIViewController的文档中不会找到它。initWithCoder 是一个类在IB中创建但在xocde中被实例化时被调用的。你可以理解为是一个解固过程,所以在这个时候view还没初始化,你可以完成一些需要在view未初始化之前调用的方法。注意这个方法在生命周期中只会调用一次。

2.awakeFromNib
当.nib文件或storyBoard文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件或storyBoard文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行一些必要的操作。也就是说通过nib文件创建view对象时执行awakeFromNib

如果你不是从.nib文件或storyBoard文件中加载view,你可以在loadView方法通过代码初始化view。

3.viewWillLayoutSubviews和viewDidLayoutSubviews

viewWillAppear和viewDidAppear前会调用改方法,主要是和布局相关。在当几何方向改变时也会再次调用以下方法,例如旋转方向变化。
(当选择方向改变还会收到 will/didRotateTo/From messages)

再说下可能会看到的initWithNibName 和 loadNibNamed。
主要是用于加载子view,使用此方法加载用户界面(xib文件)到我们的代码中,这样,可以通过操作这个加载进来的(xib)对象,来操作xib文件内容。 它们之间的区别是initWithNibName方法:是延迟加载,这个View上的控件是 nil 的,只有到 需要显示时,才会不是 nil 。
loadNibNamed方法:即时加载,用该方法加载的xib对象中的各个元素都已经存在。

- (void)submitShare:(id)sender
{
    if (![self checkInputContentLegal]) {
        return;
    }
    [_textView resignFirstResponder];
    if (!_locationEnable) {//如果不显示地理位置
        _latitude = 0;
        _longtitude = 0;
        NSLog(@"不显示地理位置");
    }else{
        NSLog(@"显示地理位置,%f,%f",_latitude,_longtitude);
    }
    NSString *accseeToken = [AccountTool sharedAccountTool].account.accessToken;
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:kUploadURL]];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    __weak typeof(self) weakSelf = self;
    NSString *encodeStatus = _textView.text;
    if (_images.count == 0) {
        [manager POST:@"2/statuses/update.json"
           parameters:@{@"access_token": accseeToken,
                             @"status" : encodeStatus,
                             @"visible" : @(_intVisible),
                             @"lat" : @(_latitude),
                             @"long" : @(_longtitude)}
              success:^(NSURLSessionDataTask *task, id responseObject) {
                  NSLog(@"发送成功");
                  [self showSuccessHUD];
                  [self performSelector:@selector(back) withObject:self afterDelay:1.5];
                }
              failure:^(NSURLSessionDataTask *task, NSError *error) {
                  [self showFailHUD];
                  NSLog(@"发送失败");
                }];
    }else{
        [manager POST:@"2/statuses/upload.json"
           parameters:@{@"access_token": accseeToken,
                           @"status" : encodeStatus,
                           @"visible" : @(_intVisible),
                           @"lat" : @(_latitude),
                           @"long" : @(_longtitude)}
            constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                NSMutableArray *images = [NSMutableArray arrayWithArray:weakSelf.images];
                for (id asset in images) {
                    NSData *data = nil;
                    if ([asset isKindOfClass:[UIImage class]]) {
                        data = UIImageJPEGRepresentation(asset, 0.4);
                    }
                    if ([asset isKindOfClass:ALAsset.class]) {
                        UIImage *original = [UIImage imageWithCGImage: [[asset defaultRepresentation] fullScreenImage]];
                        data = UIImageJPEGRepresentation(original, 0.4);
                    }
                    [formData appendPartWithFileData:data name:@"pic" fileName:@"pic.jpg" mimeType:@"multipart/form-data"];
                    //新浪开放的API一次只能上传一张图片,选择多张的时候会使用最后一张,通过调用[http://open.weibo.com/wiki/2/statuses/upload_pic]() 接口生成高级接口statuses/upload_url_text中的参数pic_id,可以实习上传多张图片
                }
            } success:^(NSURLSessionDataTask *task, id responseObject) {
                NSLog(@"发送成功");
                [self back];
            } failure:^(NSURLSessionDataTask *task, NSError *error) {
                [self showFailHUD];
            }];
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容