gpt4 book ai didi

ios - UICollectionViewCell 以编程方式内存泄漏

转载 作者:行者123 更新时间:2023-12-01 19:44:24 26 4
gpt4 key购买 nike

我在不使用 Storyboard的情况下以编程方式创建了 UICollectionViewUICollectionViewCell,但是发生了一些事情,我无法理解为什么。

BKPhotoCell 中存在内存泄漏。

单元格是全屏的,但是当滚动CollectionView时,它们从未重用。 Init 在每个 indexpath.row 中被调用。

PrepareForReuse 也从未被调用过。

谁能帮助我理解我做错了什么?

- (void)viewDidLoad
{
[super viewDidLoad];

CGSize screenSize = self.view.bounds.size;
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(screenSize.width, screenSize.height)];
[flowLayout setMinimumInteritemSpacing:0.0f];
[flowLayout setMinimumLineSpacing:0.0f];
[flowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];

[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0,0, screenSize.width, screenSize.height) collectionViewLayout:flowLayout];
[self.collectionView setDelegate:self];
[self.collectionView setDataSource:self];
[self.collectionView registerClass:[BKPhotoCell class] forCellWithReuseIdentifier:@"BKPhotoCell"];
[self.collectionView setPagingEnabled:YES];
[self.collectionView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self.view addSubview:self.collectionView];

}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

BKPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"BKPhotoCell" forIndexPath:indexPath];
[cell.imageView setImage:[UIImage imageNamed:[_photos objectAtIndex:indexPath.row]]];
return cell;
}

BKPhotoCell.h:

@interface BKPhotoCell : UICollectionViewCell
@property (nonatomic, strong) UIImageView *imageView;
@end

BKPhotoCell.m:

@interface BKPhotoCell() <UIScrollViewDelegate>
@property (nonatomic ,strong) UIScrollView *scrollView;
@end

@implementation BKPhotoCell

#define isPortrait [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown

#pragma mark - ScrollView Delegate

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {

return self.imageView;
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{

CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
(scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;

CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
(scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;

_imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
scrollView.contentSize.height * 0.5 + offsetY);
}

#pragma mark - View Lifecycle

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {

self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.bounds.size.width, self.contentView.bounds.size.height)];
[self.scrollView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
[self.scrollView setContentMode:UIViewContentModeScaleAspectFit];
[self.scrollView setDelegate:self];
[self.contentView addSubview:_scrollView];

self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.bounds.size.width, self.contentView.bounds.size.height)];
[self.imageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[self.imageView setContentMode:UIViewContentModeScaleAspectFit];

[self.scrollView addSubview:self.imageView];

}
return self;
}


- (void)prepareForReuse {

[super prepareForReuse];
NSLog(@"Prepare for reuse");

}

- (void)layoutSubviews {

[super layoutSubviews];

[self.imageView setFrame:CGRectMake(0, 0, _imageView.image.size.width, _imageView.image.size.height)];
// NSLog(@"Setting Content Size: %f, %f", _imageView.image.size.width, _imageView.image.size.height);
[_scrollView setContentSize:_imageView.image.size];

CGFloat offsetX = (_scrollView.bounds.size.width > _scrollView.contentSize.width)?
(_scrollView.bounds.size.width - _scrollView.contentSize.width) * 0.5 : 0.0;

CGFloat offsetY = (_scrollView.bounds.size.height > _scrollView.contentSize.height)?
(_scrollView.bounds.size.height - _scrollView.contentSize.height) * 0.5 : 0.0;

_imageView.center = CGPointMake(_scrollView.contentSize.width * 0.5 + offsetX,
_scrollView.contentSize.height * 0.5 + offsetY);

float minimumZoomScale;

if (isPortrait) {
minimumZoomScale = _imageView.frame.size.width >= _imageView.frame.size.height ? _scrollView.frame.size.width / _imageView.frame.size.width : _scrollView.frame.size.height / _imageView.frame.size.height;
} else {
minimumZoomScale = _imageView.frame.size.width > _imageView.frame.size.height ? _scrollView.frame.size.width / _imageView.frame.size.width : _scrollView.frame.size.height / _imageView.frame.size.height;
}

[self.scrollView setMinimumZoomScale:minimumZoomScale];
[self.scrollView setMaximumZoomScale:minimumZoomScale * 2];
[self.scrollView setZoomScale:minimumZoomScale];


}

最佳答案

如果您使用的是 iOS7,则可能会遇到重用错误!

我确实有同样的问题,它在 iOS6.1iOS6 上运行良好,但一旦在 iOS7 上启动(最终)细胞永远不会被重复使用!

我没有解决办法,我正在尝试创建自己的重用逻辑。

编辑:

我有一些工作,所以你需要保存布局中的属性(如果你正在使用它,可能会覆盖FlowLayout)。

然后在

- (void)collectionView:(UICollectionView *)collectionView 
didEndDisplayingCell:(UICollectionViewCell *)cell
forItemAtIndexPath:(NSIndexPath *)indexPath

将单元格保存到 NSMutableArray

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
cellForItemAtIndexPath:(NSIndexPath *)indexPath

检查数组中的单元格并应用属性,例如:

UICollectionViewCell *cell;

if (![_removedCells count]) {
cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier
forIndexPath:indexPath];
} else {
cell = [_removedCells lastObject];
[_removedCells removeLastObject];
[cell prepareForReuse];
UICollectionViewLayoutAttributes* attr = [_layout getTempAttribute:indexPath];

[cell setFrame: attr.frame];
[cell applyLayoutAttributes:attr];

if (![cell superview]) {
[_collectionView addSubview:cell];
}
}

getTempAttribute 只是从 UICollectionViewLayout 中检索之前为我的 UICollectionViewCell 计算的 position,因此只需查找indexPath 并返回 UICollectionViewLayoutAttributes,它看起来好像工作正常并且重用 UICollectionViewCells - 但我可以'不保证任何事情;-)

Edit2:经过进一步测试,我得出的结论是,这破坏 UICollectionView 中的旋转,导致奇怪的布局问题!

关于ios - UICollectionViewCell 以编程方式内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18913382/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com