UICollectionView 重新加载(崩溃)
Posted
技术标签:
【中文标题】UICollectionView 重新加载(崩溃)【英文标题】:UICollectionView reload ( crash ) 【发布时间】:2013-09-06 12:19:29 【问题描述】:我有一个集合视图,当我最初加载数据时该视图工作正常,但当我尝试重新加载它时崩溃。看看方法上发生的重新加载 - scrollViewDidEndDecelerating
错误是
-[FeedCollectionViewCell release]: message sent to deallocated instance 0x800d6f70
这里是代码。
这是Controller
:
@interface MyViewController : UIViewController <UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout, UIScrollViewDelegate>
@property (retain, nonatomic) IBOutlet UICollectionView *collectionView;
@end
这是实现:
@implementation MyViewController
@interface FeedCollectionViewController ()
@property (nonatomic, strong) NSMutableArray *dataArray;
-(void)getData;
@end
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
// Custom initialization
if (self.dataArray == nil)
self.dataArray = [[NSMutableArray alloc] init];
return self;
- (void)viewDidLoad
[self.collectionView registerClass:[FeedCollectionViewCell class] forCellWithReuseIdentifier:[FeedCollectionViewCell reuseIdentifier]];
// Configure layout
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(153, 128)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[self.collectionView setCollectionViewLayout:flowLayout];
[self getData];
-(void)getData
// here I make a call to the server to get the data and I set the data array
self.dataArray = mydatafromserver
[self.collectionView reloadData];
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
FeedCollectionViewCell *cell = (FeedCollectionViewCell *)[cv dequeueReusableCellWithReuseIdentifier:[FeedCollectionViewCell reuseIdentifier] forIndexPath:indexPath];
[cell.label setText:[[self.dataArray objectAtIndex:indexPath.row] name];
return cell;
- (void)scrollViewDidEndDecelerating:(UICollectionView *) collectionView
NSLog(@"FeedCollectionViewController::scrollViewDidEndDecelerating");
CGPoint offset = collectionView.contentOffset;
CGRect bounds = collectionView.bounds;
CGSize size = collectionView.contentSize;
UIEdgeInsets inset = collectionView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
// NSLog(@"offset: %f", offset.y);
// NSLog(@"content.height: %f", size.height);
// NSLog(@"bounds.height: %f", bounds.size.height);
// NSLog(@"inset.top: %f", inset.top);
// NSLog(@"inset.bottom: %f", inset.bottom);
// NSLog(@"pos: %f of %f", y, h);
float reload_distance = 300;
if(y > h - reload_distance)
NSLog(@"load more rows...");
***//// FAIL HERE***
[self.collectionView reloadData];
这是单元格
#import <UIKit/UIKit.h>
#define FB_COLL_CELL_IDENTIFIER @"CollectionCellIdentifier"
@interface FeedCollectionViewCell : UICollectionViewCell
@property (retain, nonatomic) IBOutlet UIImageView *image;
@property (retain, nonatomic) IBOutlet UILabel *label;
@property (retain, nonatomic) IBOutlet UIActivityIndicatorView *spinner;
+ (NSString *)reuseIdentifier;
@end
#import "FeedCollectionViewCell.h"
#import "CustomCellBackground.h"
@implementation FeedCollectionViewCell
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
NSLog(@"FeedCollectionViewCell initWithFrame");
// Initialization code
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"FeedCollectionViewCell" owner:self options:nil];
if ([arrayOfViews count] < 1)
return nil;
if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]])
return nil;
self = [arrayOfViews objectAtIndex:0];
CustomCellBackground *backgroundView = [[CustomCellBackground alloc] initWithFrame:CGRectZero];
self.selectedBackgroundView = backgroundView;
return self;
+ (NSString *)reuseIdentifier
NSLog(@"FBDisplayCell ... static reuseIdentifier called ");
return (NSString *)FB_COLL_CELL_IDENTIFIER;
@end
这是另一个。添加这个是因为它正在被使用。我不认为问题在这里,但你永远不知道!
#import <UIKit/UIKit.h>
@interface CustomCellBackground : UIView
@end
#import "CustomCellBackground.h"
@implementation CustomCellBackground
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
// Initialization code
return self;
- (void)drawRect:(CGRect)rect
// draw a rounded rect bezier path filled with blue
CGContextRef aRef = UIGraphicsGetCurrentContext();
CGContextSaveGState(aRef);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:5.0f];
[bezierPath setLineWidth:5.0f];
[[UIColor blackColor] setStroke];
UIColor *fillColor = [UIColor colorWithRed:0.529 green:0.808 blue:0.922 alpha:1]; // color equivalent is #87ceeb
[fillColor setFill];
[bezierPath stroke];
[bezierPath fill];
CGContextRestoreGState(aRef);
@end
【问题讨论】:
您在没有 ARC 的项目中使用UICollectionView
。框架允许吗?
有没有什么好办法找出来?
不知道,一直在使用ARC
。它已经存在了很多年。你在某个地方调用[FeedCollectionViewCell release]
,而它已经发布了,这就是问题所在。
我检查了我的编译器,我正在使用这个编译器:Apple LLVM compiler 4.2
以及,关于发布。这就是我的困惑所在,我没有发布 feedCollectionViewCell。我没有用于发布的代码。
【参考方案1】:
问题在于 UICollectioViewCell -initWithFrame
我改为不加载笔尖,我开始创建自己的笔尖
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
self.backgroundColor = [UIColor colorWithWhite:0.85f alpha:1.0f];
self.layer.borderColor = [UIColor whiteColor].CGColor;
self.layer.borderWidth = 3.0f;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowRadius = 3.0f;
self.layer.shadowOffset = CGSizeMake(0.0f, 2.0f);
self.layer.shadowOpacity = 0.5f;
self.imageView = [[UIImageView alloc] initWithFrame:self.bounds];
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
self.imageView.clipsToBounds = YES;
[self.contentView addSubview:self.imageView];
return self;
【讨论】:
以上是关于UICollectionView 重新加载(崩溃)的主要内容,如果未能解决你的问题,请参考以下文章
UICollectionViewFlowLayout 子类在滚动和重新加载时崩溃访问超出范围的数组
如果在重新加载期间触摸单元格,则重新加载后无法选择 UICollectionView 单元格