我们在view编写的过程中,经常的实用这三个方法,在init中初始化,在set中给view赋值,在layoutSubviews 给view布局. 这样做的道理是init 在一个控件创建过程中,他上面的子view只会创建一次,比如:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UILabel *label = [[UILabel alloc] init];
[self addSubview:label];
}
return self;
}
这样可以保证label 只创建一次 毕竟init 只调用一次
如果在set 和 layout的中创建,会因为多次调用,会不停地创建,同时设置属性也是,写到set和layout中会浪费性能,这在cell的复用中尤为明显,
- (void)setStatus:(YYStatus *)statuses
{
UILabel *label = [[UILabel alloc] init];
[self addSubview:label];
}
这个赋值方法, 每个cell都会调用,所以label会被循环利用的cell多次创建,多次添加,修改属性也会被多次修改,造成浪费,因为cell是循环利用的,不会再调用init, 所以label只会被创建一次,在layoutSubviews里面的道理是一样的
Cell 针对有的控件有时候显示,有时候不显示(一直显示的不用判断hidden)
因为牵扯循环利用,cell中显示的控件要全部创建,然后通过是否hidden 来判断是否隐藏.
特别注意:cell上的每个控件都要在set赋值的时候判断是否隐藏,包扩view上可能显示,也可能不显示的子view
例如
for (int i = 0; i <photos.count; i++) {
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = ...
}
这样判断,如果photos.count == 5 那么剩余的四个图片 会复用前面的图片,因为你没对后面的是否hidden进行判断
正确写法
// 遍历所有的图片控件,设置图片
for (int i = 0; i<self.subviews.count; i++) {
HWStatusPhotoView *photoView = self.subviews[i];
if (i < photosCount) { // 显示
photoView.photo = photos[i];
photoView.hidden = NO;
} else { // 隐藏
photoView.hidden = YES;
}
}