「OC」视图控制器的懒加载策略

server/2024/9/24 8:57:14/

「OC」视图控制器的懒加载策略

文章目录

  • 「OC」视图控制器的懒加载策略
    • 懒加载
      • 懒加载的优点
      • 常见的懒加载实现方法
      • 使用懒加载的注意事项
    • 控制器的懒加载
    • 参考资料

懒加载

懒加载(Lazy Loading)是一种设计模式,其核心思想是在需要时才进行对象的创建或资源的加载,而不是在对象初始化时立即完成。这种技术可以提高程序的性能和效率,减少资源的消耗。懒加载特别适用于那些创建代价高、内存占用大或者初始化过程复杂的对象。

懒加载的优点

  1. 性能提升:通过推迟对象的创建,减少了程序启动时的资源消耗和初始化时间。
  2. 内存优化:对象的创建和资源的加载在实际需要时才进行,有效节省了内存。
  3. 提高响应速度:初始化时不需要加载所有资源,使得程序在启动和运行时更加响应迅速。
  4. 降低复杂度:只在需要的时候才创建和初始化对象,有助于降低系统的复杂度。

注意:如果使用懒加载的话则一定要注意进行判空,如果为空那么再去进行实例化。

常见的懒加载实现方法

在 Objective-C 中,懒加载通常是通过重写 getter 方法来实现的。以下是一个示例:

#import "ViewController.h"@interface ViewController ()@property (strong, nonatomic) UILabel *label;@end@implementation ViewController- (UILabel*) label {if (!_label) {_label = [[UILabel alloc]init];_label.font = [UIFont systemFontOfSize:45];_label.text = @"LazyLoad";_label.frame = CGRectMake(120, 400, 260, 50);_label.textColor = [UIColor blackColor];}return _label;
}- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {[self label];//点击后将label添加到视图[self.view addSubview:self.label];}- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.
}@end

得到的内容如下,当我们点击屏幕懒加载的UILabel才会显示在屏幕之上

Aug-18-2024 16-44-58

一般来说,对于需要直接加载在页面上的内容,我们不使用懒加载,直接进行普通加载即可,而那些不出现在首页需要点击才弹出的页面,才使用懒加载,可以有效缩短加载的时间

在重写getter方法的过程之中,我们只能用直接访问属性的方法进行方法(即_加上属性名),如果使用间接访问属性的方法,使用getter方法很可能引起循环引用

使用懒加载的注意事项

  1. 线程安全:在多线程环境中,确保懒加载实现是线程安全的。通常需要使用同步机制(如锁)来防止并发访问导致的问题。
  2. 性能考虑:虽然懒加载可以减少初始化开销,但也要确保在实际需要时加载的操作不会过于耗时,否则可能会影响用户体验。
  3. 内存管理:确保对象在不再需要时能够被正确释放,以避免内存泄漏。

控制器的懒加载

通过我们前面对懒加载的了解,我们现在可以在编译器进行实验

SceneDelegate.h

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;ViewController *vc = [[ViewController alloc] init];
NSLog(@"%s",__func__);vc.view.backgroundColor = [UIColor redColor];self.window.rootViewController = vc;[self.window makeKeyAndVisible];
}

ViewController.h

- (void)viewDidLoad {[super viewDidLoad];NSLog(@"%s",__func__);self.view.backgroundColor = [UIColor orangeColor];
}

我们最后得到的控制器,是一个红色背景的控

制器,似乎好像没有问题,因为我们先创建控制器,在里面对背景颜色赋值,再在SceneDelegate.h之中进行重新赋值。

不过我们可以来看看打印的内容

image-20240818181111962

NSLog(@"%s",__func__);的意思是用于在日志中打印当前函数的名称。看到打印的内容,我们先打印出来的是在- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions的方法,那么在SceneDelegate.h的赋值程序是先运行的,那么关于背景颜色的赋值和我们之前的猜想不同的。

那是怎么回事呢,我们再对程序进行打印,来印证我们的操作

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;ViewController *vc = [[ViewController alloc] init];NSLog(@"%s",__func__);NSLog(@"访问控制器属性之前");vc.view.backgroundColor = [UIColor redColor];NSLog(@"访问控制器属性之后");self.window.rootViewController = vc;[self.window makeKeyAndVisible];
}

image-20240818181857805

不难看到,只有当我们访问到控制器属性之后,才会开始运行[ViewController viewDidLoad]这个方法,也就是说只有当访问了属性控制器的视图才会开始进行加载。

我们带着这个猜想,继续进行实验,我们可以使用isViewLoaded检验控制器是否进行加载

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;ViewController *vc = [[ViewController alloc] init];if ([vc isViewLoaded]) {vc.view.backgroundColor = [UIColor redColor];}self.window.rootViewController = vc;[self.window makeKeyAndVisible];
}

我们可以看到,控制器的背景反而变成了橙色,说明当我们创建了控制器,控制器并不会马上加载,而是我们将控制器作为UIWindow的根视图时或者访问到了控制器的属性,控制器才会进行加载。通过以上示例,我们其实不难发现,懒加载这个方法是在iOS的开发之中随处可以领略到的一个思想

参考资料

【iOS】懒加载

4.10 控制器View的懒加载


http://www.ppmy.cn/server/103899.html

相关文章

Python-基础-数字处理

文章目录 数字处理1 数值类型2 基本运算3 数学函数4 随机函数 数字处理 1 数值类型 Python3三种数值类型&#xff0c;分别是&#xff1a;整型&#xff08;int&#xff09;、浮点型&#xff08;float&#xff09;、复数&#xff08;complex&#xff09; 低版本 Python2的还包…

Excel的使用总结

目录 1、汇总公式&#xff1a;TEXTJOIN 2、excel中选择某个区域的方法 3、excel中如何在复制的时候&#xff0c;不将公式一起复制过去 4、想要自动填充某个区域的值的方法 1、汇总公式&#xff1a;TEXTJOIN TEXTJOIN 函数 - Microsoft 支持 例&#xff1a;TEXTJOIN("…

STM32GPIO引脚八种工作模式

1. GPIO简述 GPIO&#xff08;General-purpose input/output&#xff09;&#xff0c;通用型输入输出。简单理解就是我们可以控制输入输出的STM32引脚&#xff0c;统称为GPIO。 GPIO存在的意义就是用程序控制或读取它们的输出或输入。 2. 功能描述 每个GPI/O端口有两个32位配…

Android 10.0 锁屏页面忘记锁屏密码情况下点击5次解锁图标弹出锁屏密码功能实现

1. 前言 在10.0的系统ROM定制化开发中,在一些产品中带锁屏密码的功能中,系统默认是滑动解锁,但是客户会设置锁屏密码,在某些时候会 忘掉锁屏密码,导致需要进入恢复出厂设置然后才能进入系统桌面,这样就导致系统的保存的资料都丢失了,所以需要要求在锁屏密码页面在忘记解…

SQL进阶技巧:最近有效的缺失值填充问题【last_value实现版】

目录 0 场景描述 1 数据准备 2 问题分析 3 小结 0 场景描述 场景:现在有一张商品入库表,包括商品id、商品成本和入库日期3个字段,由于某些原因,导致部分商品的成本缺失(为0或者没有值都是缺失),这样不利于我们计算成本。所以现在要把缺失的商品进价补充完整,补充的…

LLama 3 跨各种 GPU 类型的基准测试

2024 年 4 月 18 日&#xff0c;AI 社区对 Llama 3 70B 的发布表示欢迎&#xff0c;这是一款最先进的大型语言模型 &#xff08;LLM&#xff09;。该型号是 Llama 系列的下一代产品&#xff0c;支持广泛的用例。该模型 istelf 在广泛的行业平台上表现良好&#xff0c;并提供了新…

<数据集>水面垃圾识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;4308张 标注数量(xml文件个数)&#xff1a;4308 标注数量(txt文件个数)&#xff1a;4308 标注类别数&#xff1a;1 标注类别名称&#xff1a;[Trash] 序号类别名称图片数框数1Trash43085593 使用标注工具&#x…

番外-PyTorch细节知识

文章目录 一、torch.nn.Parameter1.1 Parameter与buffer的区别1.2 nn.Module类中实现注册Parameter的机制 二、Pytorch 中的 Tensor , Variable & Parameter2.1 Tensor2.2 Variable2.3 Parameter 三、pytorch的常用函数总结3.1 .data 与 .detach3.2 .scatter 与 ._scatter3…