カスタム UICollectionViewCells を含む UICollectionView があります (TestReceiptCell はクラス名です)。
カスタムセルにUILabelのみが含まれている場合、UICollectionViewを表示してカスタムセルをロードするのに問題はありませんでした。
次に、IB を介して UITableView を TestReceiptCell NIB ファイルに追加しました。UITableView の TestReceiptCell.h に参照アウトレットを設定し、.m ファイルに合成しました。UITableView のデリゲートとデータソースを、UICollectionView を含む ViewController に設定します。
アプリを実行すると、3 行目のこのブロックで EXC_ BAD_ ACCESS 例外が発生します。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"TestReceiptCell";
TestReceiptCell *cell = (TestReceiptCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; //exception thrown here
return cell;
}
Zombie Instrument テストを実行したところ、割り当て解除されたメモリ呼び出しがここで発生していることがわかりました。その機器を使用するのはこれが初めてなので、ここから調査する方法が正確にはわかりません。
参考までに、コードの関連部分をいくつか示します。
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.myCollectionView registerNib:[UINib nibWithNibName:@"TestReceiptCell" bundle:nil] forCellWithReuseIdentifier:@"TestReceiptCell"];
// Setup flowlayout
myCollectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[myCollectionViewFlowLayout setItemSize:CGSizeMake(310, 410)];
[myCollectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.myCollectionView setCollectionViewLayout:myCollectionViewFlowLayout];
self.myCollectionView.pagingEnabled = YES;
}
ViewController.m ファイルにも UITableView データソースとデリゲート メソッドを実装していますが、EXC_BAD_ACCESS 例外が発生したため、ここに問題があるかどうかはわかりません。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:@"eventCell"];
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"eventCell"];
}
return cell;
}
アップデート:
cellForItemAtIndexPath を次のように変更すると、これを実行できます。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"TestReceiptCell";
//TestReceiptCell *cell = (TestReceiptCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
TestReceiptCell *cell = [NSBundle.mainBundle loadNibNamed:@"TestReceiptCell" owner:self options:nil][0];
return cell;
}
ただし、セルをデキューしているのではなく、これが正しい方法ではないことはわかっています。dequeueReusableCellWithResueIdentifier が新しいセルを作成するときに呼び出される initWithFrame メソッドのどこかに問題があるようです。現在、その方法は次のとおりです。
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"TestReceiptCell" owner:self options:nil];
if ([arrayOfViews count] < 1) {
return nil;
}
if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
return nil;
}
self = [arrayOfViews objectAtIndex:0];
}
return self;
}
編集:
テーブルビューのデリゲートまたはデータソースを選択しないと、テーブルビューを含むコレクションビューが読み込まれます。デリゲート/データソースをファイルの所有者にアタッチすると、エラーが発生します。