iOS开发之旅之懒加载

作者: Top_熊 | 来源:发表于2015-05-29 00:12 被阅读36593次

在iOS开发摸爬打滚了许久,谈谈自己学习以及开发iOS的一些经验,文章比较随性,算是记录自己的成长吧!希望有些我走的弯路以及曾经让我捉耳挠腮的问题可以帮助读者少走一些弯路。

本文来谈一谈在开发中非常实用的懒加载技术吧!

  • 所谓的懒加载可以定义为:延时加载,即当对象需要用到的时候再去加载。其实就是所谓的重写对象的get方法,当系统或者开发者调用对象的get方法时,再去加载对象。
    需要注意:重写get方法时,先判断对象当前是否为空,为空的话再去实例化对象
  • 懒加载的优点
    • 不需将对象的实例化写到viewDidLoad,可以简化代码,增强代码的可读性
    • 对象的实例化在getter方法中,各司其职,降低耦合性
    • 对系统的内存占用率会减小

viewDidLoad正常加载代码示例

  • 没用懒加载的时候,从plist获取数据,返回一个数组,需要写在viewDidLoad方法中获取
@interface ViewController ()

@property (nonatomic, strong) NSArray *shopData;

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    _shopData = [NSArray arrayWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"shop" ofType:@"plist"]];
}

@end```

- 显而易见,当控制器被加载完成后就会加载当前的shopData,假如shopData是在某些事件被触发的时候才会被调用,没必要在控制器加载完就去获取plist文件,如果事件不被触发,代表着shopData永远不会被用到,这样在viewDidLoad中加载shopData就会十分多余,并且耗用内存

#### 懒加载代码示例
```objc
- (void)viewDidLoad {
    
    [super viewDidLoad];
}

- (NSArray *)shopData
{
    if (!_shopData) {
        _shopData = [NSArray arrayWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"shop" ofType:@"plist"]];
    }
    return _shopData;
}

@end```
- 当需要用到shopData的时候,就会调用[self shopData]的方法(即getter方法),此时系统会去调用getter方法,然后再getter方法中获取plist文件内容,然后返回使用(需要注意在getter方法里切勿使用self.shopData,因为self.shopData会调用getter方法,造成死循环)
#### 总结:懒加载即用到时方去加载对象

相关文章

  • iOS 数组 NSArray 遍历 懒加载总结

    iOS开发之懒加载 iOS中数组遍历的方法及比较

  • iOS开发之旅之懒加载

    在iOS开发摸爬打滚了许久,谈谈自己学习以及开发iOS的一些经验,文章比较随性,算是记录自己的成长吧!希望有些我走...

  • iOS开发之旅之懒加载

    在iOS开发摸爬打滚了许久,谈谈自己学习以及开发iOS的一些经验,文章比较随性,算是记录自己的成长吧!希望有些我走...

  • iOS开发之懒加载

    iOS开发之懒加载 在iOS开发中几乎经常用到懒加载技术,比如我们存放网络数据的数组,控制器的view,控件的自定...

  • Swift的懒加载和只读属性的介绍

    懒加载 在 iOS 开发中,懒加载是无处不在的 懒加载的格式如下: lazy var person: Person...

  • iOS开发之懒加载

    所谓的懒加载可以定义为:延时加载,即当对象需要用到的时候再去加载。其实就是所谓的重写对象的get方法,当系统或者开...

  • iOS 开发之懒加载

    1.懒加载基本 懒加载 -- 也称为延迟加载,即在需要的时候才加载(效率低,占用内存小)。所谓懒加载,写的是其ge...

  • 2018-12-21

    iOS开发中懒加载遇到的坑 正常写一个懒加载对象 - (MAMapView*)mapView{ if(nil=...

  • # 懒加载

    在 iOS 开发中,懒加载是无处不在的 懒加载的格式如下: 懒加载本质上是一个闭包 以上代码可以改写为以下格式 懒...

  • iOS开发-懒加载

    懒加载,⼜又称为延迟加载。说的通俗⼀一点,就是在开发中,当程序中需要 利⽤用的资源时。在程序启动的时候不加载资源,...

网友评论

  • _安迪_:一直搞不懂懒加载的意义何在?你直接定义一个NSArray,不初始化的时候也是nil呀,感觉重写getter的唯一好处就是你在调用的时候不需要判断是不是nil了而已。
    而楼主上面的例子代码,感觉也是毫无任何意义,把NSArray初始化代码写在viewDidLoad里,当然是加载控制器的时候就加载NSArray了,说明你要用了。后面重写了getter,如果你把[self shopData]写在viewDidLoad不也就一开始就加载了?有什么区别?
    _安迪_:不应该说懒加载没意义,应该是说这种重写getter的方式其实不是懒加载
  • 灯泡虫:懒加载自动编码 从此解放你的双手 http://www.jianshu.com/p/e6e6e10421aa :grin:
  • 93b3d3ccb7e6:楼主这句话说错了:" 需要注意在getter方法里切勿使用self.shopData,因为self.shopData会调用getter方法,造成死循环 "。

    代码验证如下:

    ```
    @interface ViewController ()

    @property (nonatomic, strong) NSMutableArray *dataSource;

    @EnD

    @Implementation ViewController

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSLog(@" -->> dataSource:%@", self.dataSource);
    }

    - (NSMutableArray *)dataSource{

    if (!_dataSource) {
    self.dataSource = [NSMutableArray array];
    }
    return _dataSource;
    }
    ```
    无夜之星辰:@书中觅宝 :smirk:
    93b3d3ccb7e6:@无夜之星辰 我也是醉了:smiley:
    无夜之星辰:你的一段代码竟然在无意中@到了4个人,不得不说,很强势。
  • 青空逸隐:请教一下, 我想暴露一个类方法, 并且此类方法中有一个数组需要用到懒加载,我该如何去做呢?
    大致是这样的, 懒加载获取数组 [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil]
    类方法根据传入条件去取其中一个返回
  • 4e44e356ab32:写的不错 赞一个
  • Chars:这种写法的懒加载是恨危险的
    Jason_jh:@大连小生 用了两三年个人觉得懒加载并没有很危险,只是当做一些判断时需要特别注意,比如 if(self.shopData)时需要特别注意,因为是懒加载所以此时变量始终是有值的(不会为nil),所以不可作为判断条件。不知楼上所说危险指的是什么。
    大连小生:为什么会很危险啊 大婶
    Felix灬泡泡:@Chars :flushed: 为什么呢?
  • RiversMa:既然数组写了肯定会用到,加载是必须的,只不过迟早问题,感觉懒加载意义不大!
  • DockLee:如果使用了Masonry,控件需要先addSubview,然后再定义控件的布局,对于使用了Masonry的控件,不知有没有什么想法?
    Top_熊:@DockLee 我个人更喜欢重写子空间的layoutsubviews重新布局
  • 原来可以这样:今天不小心使用懒记载的时候栽到self这个问题上面了,但是我做的和你们说的却有点出入,我看你们都说不要在懒加载初始化的时候使用self,避免循环引用,我确是在懒加载的alloc的时候使用self掉用属性来完成初始化,其它的都和你们的一样用下划线的去判断,返回的时候也是带下划线。 但是在第一次用到这个属性的时候我都是使用的self去掉用属性,其它的时候随意(下划线或者self),如果第一次用到这个属性不使用self,就会产生初始化不成功,这是为什么呢?
    郭鵬飛on:@原来可以这样 懒加载在初始化的时候_、调用的时候得用self
  • b8ae8d7cb19a:多写点啊
  • ouis:在set方法中,self.shopData = data,相当于[self setshopData: data].在get方法中,return self.shopData ,相当于[self shopData].
  • 超_iOS:5楼+1,但是在里边用self.确实有造成crash的可能,但不知道是为什么.我一般尽量不用self.,还请大神明示
    墨狂之逸才:你crash的代码是怎么样的,贴出来看看,二楼Twistar说: 只要return _shopData;不要写成return self.shopData;就不会构成死循环.
    上面的_shopData写成self.shopData只是调用setter方法,不会构成死循环.
    超_iOS:@维尼的小熊 在=左边是setter啊,并没有循环
    Top_熊:@小菜超 self等于调用get方法,你现在就在重写get方法,死循环了
  • 4de039cceacb:有个疑问,不知道楼主是不是能解答。就是当我们使用 if (!_shopData) 这种方法去判断是否为空的时候,!_shopData 这句如果代码来表示的话,是等价于什么逻辑判断的呢?是 _shopData != nil 还是 ![_shopData isEqual:[NSNull null],还或者有其他的逻辑判断?
    4de039cceacb:@colhy 但是,我遇到_shopData被赋了[NSNull null]的时候,if (_shopData != nil)没有用,但if (!_shopData)能够跳过这个坑。
    colhy:@机器猫的百宝袋 !_shopData 等价于 (_shopData == nil)
    _shopData为nil的时候类似bool型的NO if (!_shopData)表示如果_shopData没有被初始化,则执行
    机器猫的百宝袋:@Solo周 是个好为题,我也想知道
  • 梓茜DiannaWong:简单易懂,很好~~菜鸟我看了也懂了,非常感谢
  • 墨狂之逸才:我也觉得没什么问题,不会造成死循环。楼上上说:iOS的点语法,放等号右边就是调用getter,放左边就是调用setter方法。getter方法里面调用setter方法没什么问题啊???
    墨狂之逸才:@HeminWon 我理解有点偏差:至于这个点语法代表的是get方法还是set方法,那就取决于你是取值还是设值,取值就是get方法,设值就是set方法。其他还有什么问题吗?
    HeminWon:@墨狂之逸才 http://www.cnblogs.com/mjios/archive/2013/04/08/3006577.html
    机器猫的百宝袋:@墨狂之逸才 对,认同你的理解
  • 燕语呢喃嗅花香:里面提到:需要注意在getter方法里切勿使用self.shopData,因为self.shopData会调用getter方法,造成死循环。我能理解为什么使用它会造成死循环,我想问的是, _shopData = [NSArray arrayWithContentsOfFile:
    [[NSBundle mainBundle] pathForResource:@"shop" ofType:@"plist"]];换成self.shopData = [NSArray arrayWithContentsOfFile:
    [[NSBundle mainBundle] pathForResource:@"shop" ofType:@"plist"]];应该是没关系的吧,只要不在getter方法中的右边使用点方法应该不会造成死循环吧
    机器猫的百宝袋:@桃花流水鳜鱼肥 没关系吧。
    - (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.backgroundColor = [UIColor whiteColor];
    [self test1];
    }

    -(NSString *)test1{
    if (!_test1) {
    _test1 = @"test1";
    }
    self.test1 = @"test2";
    return _test1;
    }
    桃花流水鳜鱼肥:@燕语呢喃嗅花香 有关系的,这就是个getter方法。不过这里我觉得可以用,因为实例已经存在的情况下if会判否
    b7ac9371e916:@燕语呢喃嗅花香 用下划线访问的书成员变量,不调用getter方法,点语法才会调用getter方法。
  • 阿曌:浅显易懂,谢谢分享。
  • 4cb7df9cbfee:为什么使用self.shopData,会造成死循环?能详细解释一下么?
    e4d2e01eae5e:_shopData是直接调用instance variable
    Apple建议只在getter/setter中使用
    阿曌:楼上正解,这就是iOS的点语法,放等号右边就是调用getter,放左边就是调用setter
    icoder:@带你飞啊飞 实际上self.shopData是方法调用,详细的方法是[self shopData], 一旦使用self.shopData 就导致自己调用自己的方法了

本文标题:iOS开发之旅之懒加载

本文链接:https://www.haomeiwen.com/subject/pxwrqttx.html