【iOS】懒加载

懒加载

懒加载的概念

懒加载是 iOS 开发中一个非常重要且常用的设计模式,也称延迟加载。它的核心思想是:一个对象的初始化被延迟到第一次真正需要它的时候,从而节省内存和提高性能。

在 iOS 开发中, 懒加载有以下几个常用场景:

  • 图片加载:为避免一次性加载图片过多而导致内存压力过大,因此使用懒加载在需要图片时再加载并显示图片。
  • 视图控制器的子视图:在视图控制器中,有些子视图只需要在特定条件下显示,而不是每次视图控制器加载时都需要,因此需要使用懒加载来延迟加载这些子视图,从而提高视图控制器的的加载性能。
  • 数据加载:在需要从网络请求或数据库获取数据时,可以使用它懒加载在需要时请求数据,并将数据缓存下来,避免重复请求。

懒加载的实现

  • 创建属性:在对象接口中声明一个属性,并在私有成员变量中创建一个实例变量来保存这个属性。
  • 重写getter方法:在getter方法中 ,检查私有成员变量是否已经被初始化,如果没有,则进行初始化。
  • 懒加载初始化:在getter方法中进行懒加载的初始化,根据需求创建对象、加载图片数据、进行网络请求数据等。
  • 返回实例:将初始化后的对象或资源返回给调用者。

注意⚠️

  1. 我们在创建属性时,必须使用strong关键字修饰。这是因为strong修饰的对象在被销毁时,不会被释放;而weak修饰的对象在被销毁时,weak指针自动指向nil。也就是说,当我们创建并初始化控件后,还未来得及将其赋值给一个指针并添加到视图上时就已经被自动释放掉了,也就是创建失败。
  2. 懒加载我们更常用直接访问实例变量的方法来实现。懒加载本身就是一个重写的getter方法,因此使用直接访问实例变量的方法可以防止循环引用。

直接访问成员变量 🆚 间接访问成员变量:

  • 直接访问成员变量 (_):使用 _ 可以跳过setter和getter方法。也就是说,如果getter方法中实现了一些特殊逻辑,使用 _ 可以直接跳过这些逻辑。
  • 间接访问成员变量(self):使用self可以调用属性的setter和getter方法,这样如果getter方法中有特殊逻辑,则会被处理。
objective-c 复制代码
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property(nonatomic, strong) UILabel *label;
@property(nonatomic, strong) UIButton *testButton;

@end
  
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.label];
    [self.view addSubview:self.testButton];
}

-(UILabel*) label {
    if (!_label) {
        _label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
        _label.text = @"iOS";
        _label.font = [UIFont systemFontOfSize:20];
        _label.textColor = [UIColor blackColor];
        NSLog(@"懒加载初始化");
    }
    return _label;
}

- (UIButton *)testButton {
    if (!_testButton) {
        _testButton = [UIButton buttonWithType:UIButtonTypeSystem];
        _testButton.frame = CGRectMake(100, 300, 150, 50);
        [_testButton setTitle:@"点击生成" forState:UIControlStateNormal];
        _testButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
        [_testButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _testButton.backgroundColor = [UIColor systemBlueColor];
        _testButton.layer.cornerRadius = 8;
        [_testButton addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];
    }
    return _testButton;
}

- (void)buttonTapped {
    [self.view addSubview:self.label];
}

@end 

展示一下效果:

看的出来,只有在一次初始化时会NSLog一下,而后面再点击按钮时,都不会再初始化,只会复用现有的label。

懒加载的优缺点

  • 优点
    • 节省内存:对象只在真正需要的时候才创建,避免不必要的内存占用。
    • 提高性能:应用启动时不用一次性创建所有控件或数据,页面初始化更快。
    • 节省资源:避免在对象初始化时立即加载数据或执行操作,只有在真正需要时才进行加载或执行,从而节省了不必要的资源消耗。
  • 缺点
    • 首次访问时有延迟:第一次访问时才创建对象,如果对象很大(比如图片、数据库连接),可能会导致 瞬时卡顿。
    • 多线程下可能有风险:如果多个线程同时访问懒加载的属性,可能出现重复初始化或线程安全问题。
    • 额外的资源消耗:虽然懒加载避免了一开始就加载所有数据,但在需要时仍需要进行加载,这会带来一定的资源消耗,特别是在网络请求或读取大量数据时。
相关推荐
牛奔2 分钟前
macOS 使用 conda,同时本地安装了python,遇到 ModuleNotFoundError: No module named ‘xxx‘` 解决
开发语言·python·macos·conda
川川菜鸟1 小时前
Codex+ 中转 API 部署教程(Mac版)
macos
rockage2 小时前
【技巧】MacOS下使用LaunchDaemons实现开机自启动
macos
青花锁3 小时前
Mac电脑安装Docker
macos·docker·容器
Swift社区1 天前
如何在 SwiftUI 中对 CoreImage 滤镜做实时预览
ios·swiftui·cocoa
李玮豪Jimmy1 天前
MacOS 上安装 JDK 并实现多版本灵活切换
macos
mixboot1 天前
VoxCPM 1.5.0 macOS
macos·voxcpm
甜可儿1 天前
mac环境安装不同版本maven
java·macos·maven
bl4ckpe4ch1 天前
从零开始Mac OS 开荒整理笔记
笔记·macos·开荒
七月巫山晴1 天前
【iOS】OC中的一些宏
前端·ios·objective-c