您的位置:首页 > 移动开发 > IOS开发

iOS内存话题: 弱引用下的懒加载

2016-05-20 23:56 597 查看
阅读下面的内容之前, 你应该知道什么是懒加载, 话句话说就是延时加载.

今天跟大家聊聊对于一个弱引用对象如何使用懒加载, 以及注意事项!

直接上例子.

工程比较简单, 只有一个 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, 系统就不会回收了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: