您的位置:首页 > 其它

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

2015-12-18 23:00 141 查看
在UI中,使用懒加载,也就是延迟加载来加载数据的时候,总是会面临几个问题?

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

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

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

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

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

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

#import "ViewController.h"

@interface ViewController ()
//先创建一个属性  (因为需要加载由字典组成的这个数组(也就是plist文件),所以需要先定义数组属性来接收和表示,)
@property (nonatomic, strong) NSArray *pictures;
@end

@implementation ViewController

//.重写pictures属性的get方法, 在该属性的get方法中读取images.plist文件中的数据, 并将数据设置给pictures属性
// 这种加载数据的方式就叫做"懒加载"
- (NSArray *)pictures {
if (_pictures == nil) {
// 读取plist文件并加载数据
// 1. 获取images.plist文件的完整的路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"images.plist" ofType:nil];
// 2. 根据plist文件的路径, 加载plist文件,再赋值给数组
_pictures = [NSArray arrayWithContentsOfFile:path];
}
return _pictures;
}
@end

// 封装一个修改界面控件数据的方法
- (void)loadData {
// 2. 取出当前self.pictures中的对应的数据
NSDictionary *dict = self.pictures[self.index];

// 3. 把数据设置到界面中对应的控件上
self.lblTitle.text = dict[@"desc"];  // 1
self.imgViewIcon.image = [UIImage imageNamed:dict[@"icon"]];
self.lblIndex.text = [NSString stringWithFormat:@"%d / %ld", self.index + 1, self.pictures.count];   //2

// 设置"上一张"按钮 和 "下一张" 按钮的状态
self.btnPrevious.enabled = (self.index <= 0) ? NO : YES;
self.btnNext.enabled = (self.index >= self.pictures.count - 1) ? NO : YES;
}


原因及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才能避免!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: