阅读下面的内容之前, 你应该知道什么是懒加载, 话句话说就是延时加载.
今天跟大家聊聊对于一个弱引用对象如何使用懒加载, 以及注意事项!
直接上例子.
工程比较简单, 只有一个 ViewController.
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, weak) UIButton *buton;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect rect = CGRectMake(100, 200, 100, 50);
self.buton.frame = rect;
[self.view addSubview:self.buton];
[self.buton addTarget:self
action:@selector(changeTheBkc:)
forControlEvents:UIControlEventTouchUpInside];
}
- (UIButton *)buton
{
if (nil == _buton) {
_buton = [UIButton buttonWithType:UIButtonTypeCustom];
[_buton setTitle:@"我是一个按钮" forState:UIControlStateNormal];
[_buton setBackgroundColor:[UIColor blueColor]];
}
return _buton;
}
- (void)changeTheBkc:(id)sender
{
UIColor *color = [UIColor redColor];
[self.buton setBackgroundColor:color];
}
@end
大家可以看到, UIButton 对象 buton 是一个 weak 的引用.
你会说, 这个没有什么特殊的, 运行效果一定是一个按钮贴在视图上面.
就像下面这个样子.
其实, 运行起来, 你会发现, 屏幕一片空白.
好了, 我们来分析一下原因吧!
改造一下 viewDidload 方法
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect rect = CGRectMake(100, 200, 100, 50);
self.buton.frame = rect;
NSLog(@"--------1--------sel.button: %@", _buton);
[self.view addSubview:self.buton];
NSLog(@"--------2--------sel.button: %@", _buton);
[self.buton addTarget:self
action:@selector(changeTheBkc:)
forControlEvents:UIControlEventTouchUpInside];
NSLog(@"--------3--------sel.button: %@", _buton);
}
打印结果也许让你兴奋
弱引用的对象, 在使用完成(懒加载的方法中, 即其 get 方法), 被系统回收了.
这个时候, 你也许想到, 把这个对象改为 strong 不就行了吗?
是的, 可以这么干.
但是, 我想说, 还有一种方式, 如果你以前经历过 MRC 的编码, 可能会很快明白其中的原理.
接下来, 我们修改一下懒加载的代码.
- (UIButton *)buton
{
if (nil == _buton) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"按钮" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:btn];
_buton = btn;
}
return _buton;
}
在 viewDidload 中, 修改一下代码
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect rect = CGRectMake(100, 200, 100, 50);
self.buton.frame = rect;
NSLog(@"--------1--------sel.button: %@", _buton);
[self.buton addTarget:self
action:@selector(changeTheBkc:)
forControlEvents:UIControlEventTouchUpInside];
NSLog(@"--------2--------sel.button: %@", _buton);
}
运行, 可以看到效果了, 一个蓝色的 UIButton 在那里 出现了.
到这里, 唯一一个疑惑就是, 这里为毛显示了~
大家, 应该注意到这句 code
[self.view addSubview:btn];
这里, 临时对象 btn 在 addSubview 的时候, 被 retain 一次, 所以赋值给 buton, 系统就不会回收了!