IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【iOS】—— 懒加载 -> 正文阅读

[移动开发]【iOS】—— 懒加载

一.懒加载的概念

我们使用的iOS设备其内存都有一定的限度,如果在程序启动时就将程序内的所有资源(数据,图片,视频)都加载完,那么有可能耗尽我的iOS设备的内存。

所以iOS出现了懒加载,懒加载也称延迟加载(比如控制器的view的创建),就是在开发中,当程序启动时不一次性加载所有的资源,而是在需要一些资源的时候程序才去加载这些资源(效率低,占用内存小),所谓的懒加载,其实就是对实例的getter方法的重写。

用更清晰的说法懒加载就是,一个view的子控件 ,只有当这个view被显示的时候才去加载。一个tableViewCell中,给他设置了图片,他的contentView里面才包含imageView的图片,只有设置了textLabel的内容,才会加载这个textLabel

二.懒加载的使用

//创建一个可变数组
@property (nonatomic, strong) NSMutableArray *dataArray;

@property (nonatomic, strong) UILabel *titleLabel;

至于为什么必须使用strong的原因,strong会使修饰对象的引用计数加一,而weak不会,如果一个对象的引用计数为0的话系统就会自动将其销毁。如果你想让一个控件的生命周期随着你的控制器被销毁才去释放,那就使用strong;如果你仅仅是想让它在被移除视图之后就被销毁,那就使用weak。当你使用懒加载将实例变量初始化后若使用weak修饰并且没有在其getter方法中添加到视图上时,即使你懒加载写的再好,它所返回的都是nil,即你的对象被销毁了,你的懒加载就如同空有一样。

  • 因为懒加载就是重写这个属性对应的getter方法,所以我们将要实现的逻辑放在getter中。
//重写这个属性
-(NSMutableArray *)dataArray {
//判断可变字符串是否已经存在,若没有,则进行实例化
    if (_dataArray == nil) {
        _dataArray = [[NSMutableArray alloc] init];
    }
    return _dataArray;
}

-(UILabel *)titleLabel {
    if (!titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.textColor = [UIColor blueColor];
        _titleLabel.text = @"lazyLoad";
        [self.view addSubview:_titleLabel];
    }
    return _titleLabel;
}

必须完全按照这种格式,因为如果将括号中任意一个_titleLabel换做self.titleLabel,所谓的点语法,就相当于调这个方法,在外部调用点语法时就形成无限循环,具体原因看下面注意事项的说明。

  • 懒加载的使用
    调用的时候要用自己重写的getter方法。
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self titleLabel];
}


- (UILabel*)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.textColor = [UIColor blueColor];
        _titleLabel.text = @"lazyLoad";
        _titleLabel.frame = CGRectMake(100, 100, 100, 30);
        [self.view sizeToFit];
        [self.view addSubview:_titleLabel];
    }
    return _titleLabel;
}

或者

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self.view addSubview:self.titleLabel];
}


- (UILabel*)titleLabel {
    if (!_titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.textColor = [UIColor blueColor];
        _titleLabel.text = @"lazyLoad";
        _titleLabel.frame = CGRectMake(100, 100, 100, 30);
        [self.view sizeToFit];
    }
    return _titleLabel;
}

三.懒加载的注意事项

注意一:指针循环引用问题

    if (_dataArray == nil)  不可以写成    if (self.dataArray == nil) ,不然会造成循环引用指针
    
    return _dataArray 不可以写成return self.dataArray 不然会形成循环引用

_titleLabel为成员变量,是由属性附加生成的成员变量,而self.titleLabel则为调用属性titleLabel的点语法,在没有重写titleLabel的点语法之前两者返回的是同一个东西,例如:

当调用titleLabelsetter方法调用的是下面的方法:

- (void)settitleLabel:(UILabel *)titleLabel{
     _titleLabel = titleLabel;
}

再调用titleLabel的点语法self.titleLabel调用的是下面这个方法:

- (UILabel *)titleLabel{
     return _titleLabel;
}

这就使调用self.titleLabel和直接调用_titleLabel的结果是相同的。
重写之后self.titleLabel返回的是懒加载初始化后的对象,而直接调用_titleLabel则返回的是未初始化的对象,所以我们在使用懒加载时一定要注意自己的书写,防止出现循环引用的问题。

注意二:关于布局的问题

如果用Masonry布局页面的话,关于frame的代码一定不能放在重写的getter方法里,不然会报找不到父视图的错误,要放在addSubview后面。
Masonry 是一种非常流行的第三方布局框架,它是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了,并具有高可读性,而且同时支持 iOS 和 Max OS X。
想要详细了解Masonry可以看看这两篇文章:iOS自动布局——Masonry详解iOS自动布局框架-Masonry详解

注意三:不会出现死循环的方法:

当然,还有另外一种只要你记住, 就随便你怎么写,并且万无一失、永远也不会造成死循环的方法,那就是懒加载的方法名不要和懒加载内部的实例变量同名,这样Xcode就可以准确识别出你调用的是属性还是懒加载方法,比如:

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) UILabel *label;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self lazyMethod];
}

- (UILabel *)lazyMethod {
    if (self.titleLabel) {
        _titleLabel = [[UILabel alloc] init];
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        _titleLabel.textColor = [UIColor blueColor];
        _titleLabel.text = @"lazyLoad";
        [self.view addSubview:_titleLabel];
    }
    return self.titleLabel;
}
@end

四.懒加载的优点

从上述的代码可以看出,懒加载具有一下优点:

  • 如果代码量不多,可读性略强
  • 防止了实例为 nil 的情况,减少了后续使用程序时对实例为 nil 的检查,即不用担心实例为 nil 的状况导致程序崩溃。
  • 适当使用懒加载可以节省内存资源
  • 每个属性的 getter 方法中分别负责各自的实例化方法,代码彼此之间的独立性强,降低耦合性
  • 一定程度上节省了某一期间内的时间
  • 得当使用可以优化程序性能,提高用户体验

五.懒加载的缺点

每个方法的出现都不会完美,有优点就有缺点,从上述的程序我们难想出懒加载相应的缺点:

  • 使用泛滥会导致可读性变差,每使用一次懒加载,代码就会增加几行,那么当你程序使用大量的懒加载它的代码量就会比普通方法的代码量多,看起来反而更加的繁琐,可读性自然也就没有那么强了。
  • 使用不当会导致死循环,导致crash,程序无法分清调用的是 getter 方法还是实例变量,会造成死循环。
  • 代码量增加(每增加一个懒加载,代码会平均多出3-4行)。
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 10:55:55  更:2021-08-02 10:56:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 7:01:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码