码迷,mamicode.com
首页 > 其他好文 > 详细

懒加载(延迟加载)之后,在使用数据过程中容易出现的bug

时间:2015-12-19 00:01:20      阅读:317      评论:0      收藏:0      [点我收藏+]

标签:

 

在UI中,使用懒加载,也就是延迟加载来加载数据的时候,总是会面临几个问题?

如:1. >为什么先创建NSArray属性?

    2. >为什么重写NSArray的get方法?

    3.>为什么要判断是否为空?

    4.>为什么下方代码"//1"这里不用NSString stringWithFormat: 而"//2"这里要使用? 

    5.>同时"//2"这里为什么使用的是%ld 来作为占位符?

这些问题不搞懂,懒加载就很难通透,  代码如下:

 

 1 #import "ViewController.h"
 2 
 3 @interface ViewController ()
 4 //先创建一个属性  (因为需要加载由字典组成的这个数组(也就是plist文件),所以需要先定义数组属性来接收和表示,)
 5 @property (nonatomic, strong) NSArray *pictures;
 6 @end
 7 
 8 @implementation ViewController
 9 
10 //.重写pictures属性的get方法, 在该属性的get方法中读取images.plist文件中的数据, 并将数据设置给pictures属性
11 // 这种加载数据的方式就叫做"懒加载"
12 - (NSArray *)pictures {
13     if (_pictures == nil) { 
14         // 读取plist文件并加载数据
15         // 1. 获取images.plist文件的完整的路径   
16         NSString *path = [[NSBundle mainBundle] pathForResource:@"images.plist" ofType:nil];    
17         // 2. 根据plist文件的路径, 加载plist文件,再赋值给数组
18         _pictures = [NSArray arrayWithContentsOfFile:path];
19     }
20     return _pictures;
21 }
22 @end
23 
24  // 封装一个修改界面控件数据的方法
25 - (void)loadData {
26     // 2. 取出当前self.pictures中的对应的数据
27    NSDictionary *dict = self.pictures[self.index];
28     
29     // 3. 把数据设置到界面中对应的控件上
30    self.lblTitle.text = dict[@"desc"];  // 1
31    self.imgViewIcon.image = [UIImage imageNamed:dict[@"icon"]];
32    self.lblIndex.text = [NSString stringWithFormat:@"%d / %ld", self.index + 1, self.pictures.count];   //2
33     
34     
35     // 设置"上一张"按钮 和 "下一张" 按钮的状态
36    self.btnPrevious.enabled = (self.index <= 0) ? NO : YES;
37    self.btnNext.enabled = (self.index >= self.pictures.count - 1) ? NO : YES;
38 }

原因及bug解析:

  1.>为什么先创建NSArray属性?
因为需要加载由字典组成的这个数组(也就是plist文件),所以需要先定义数组属性来接收和表示,
  2. >为什么重写NSArray的get方法?
    因为在程序运行的时候,当需要读取这个数组的数据时,此时NSArray这个数组里面是空的,空的数组是没法满足我们的需求的,所以,我们这里就拦截这个get方法,重写它,将需要的数据加载进去,这样下面运行的时候,就会有我们需要的数据了
  3.>为什么要判断是否为空?
因为程序运行时,第一次访问为空,而第二次访问就已经加载了,不为空了,所以需要判断 if (_pictures == nil),这样就避免了重复加载数据
 4.>易错点bug: 为什么代码"//1"这里不用NSString stringWithFormat: 而"//2"这里要使用? 
  
  解析:
    NSDictionary *dict=self.picture[self.index];
    self.jieshaoLabel.text=dict[@"desc"];
 
       第一种解释:这里使用的就是里面的属性, 所以可以直接用,
                      //dict[@"desc"]==等效于[NSString stringWithFormat:@"%@",dict[@"desc"]];
       第二种解释:  因为这里直接就可以引用字典中的键值对的数据了,而下面的self.suoyinLabel.text需要拼接组合数据,需要通过调用其他的属性来组成,所以需要用;
    
 5.>"//2"这里为什么使用的是%ld 来作为占位符?
 @"%ld” ,self.picture.count;    
这里是很多人都容易忽视的,所以也比较容易出现错误,
解析:
   首先我们来看看count这个属性的底层实现:
    @property (readonly) NSUInteger count;
从这个底层我们可以看得出,count是一个NSUInteger类型的,
而NSUInteger的底层又是什么呢? 我们来看看:如下:

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64

typedef long NSInteger;

typedef unsigned long NSUInteger;

#else

typedef int NSInteger;

typedef unsigned int NSUInteger;

#endif

可以看出,NSUInteger就是一个别名,而且是两种情况,

那就是如果你的设备是32位的,那么这个NSUInteger表示的就是给unsigned long取的一个别名,

那就是如果你的设备是64位的,那么这个NSUInteger表示的就是给 long取的一个别名,

所以,在使用过程中,我们首先要确定的就是当前编译器环境是处于32位,还是64位环境中,只有确定了这一步,这个bug才能避免!

 

 

 

懒加载(延迟加载)之后,在使用数据过程中容易出现的bug

标签:

原文地址:http://www.cnblogs.com/anRanTimes/p/5035881.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!