2013-02-06 64 views
1

我有一個包含自定義UICollectionViewCells(TestReceiptCell是類名稱)的UICollectionView。當我調用UICollectionViewCell dequeueReusableCellWithReuseIdentifier時,爲什麼會收到釋放的內存調用?

當自定義單元格只包含UILabel時,我沒有任何問題讓UICollectionView出現並加載自定義單元格。

然後我通過IB將UITableView添加到TestReceiptCell NIB文件中。我在TestReceiptCell.h中爲UITableView設置了一個引用出口,並在.m文件中合成。我將UITableView的委託和數據源設置爲包含UICollectionView的ViewController。

現在運行應用程序時,我就上三線在此塊EXC_ BAD_訪問異常:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 
    static NSString *cellIdentifier = @"TestReceiptCell"; 
    TestReceiptCell *cell = (TestReceiptCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; //exception thrown here 
    return cell; 
} 

我跑了殭屍儀器測試,發現瞭解除分配的內存調用源於此地。這是我第一次使用該儀器,因此我不確定如何從這裏進行調查。

僅供參考,這裏是代碼的一些相關部分:

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; 
} 

UPDATE:

我能夠得到這個,如果我改變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; 
} 

編輯:

如果我不選擇委託或爲實現代碼如下數據源,以tableviews的的CollectionView將加載。將委託/數據源附加到文件所有者的事情會導致錯誤。

+0

您可能在'TestReceiptCell'和'FullReceiptCell'之間爲集合視圖單元混合了? – Yaman

+0

啊 - 粗心的問題在我的最後問...忘了重新編碼正確的代碼。我修改了這個問題,謝謝。 – IkegawaTaro

回答

2

當您爲單元重用註冊一個UINib時,dequeueReusableCellWithReuseIdentifier:forIndexPath:是在您註冊的UINib上調用instantiateWithOwner:options:的方法。無論它傳遞給所有者,您的筆尖中的文件所有者出口是什麼。

看來你期望文件的所有者是UICollectionView,但我不認爲它是。

即使它是,我不認爲你應該使用UICollectionView的每個集合單元格中包含的UITableView的代表。這需要您的UICollectionView跟蹤每個單元格中的tableViews和內容。

我建議將包含tableView的委託設置爲收集單元本身,並讓每個單元管理自己的tableview。

編輯:

您可以爲您的集合視圖細胞相關的表視圖事件傳達給集合視圖的委託協議。通過這種方法,您可以爲集合視圖數據源的collectionView:cellForItemAtIndexPath方法設置您爲每個集合單元定義的委託屬性。

例如,當用戶從表中選擇一個項目時,您可以調用單元委託來通知集合視圖選擇哪個項目。

該方法允許您抽象說明收集單元使用表視圖顯示單元信息的事實。稍後,如果您決定要使用嵌入式UICollectionView來顯示這些項目,則代理協議可以保持不變,並且可以將更改隔離到收集單元。

+0

謝謝。我通過在我的ViewController的.m文件的'cellForItemAtIndexPath'方法中設置每個表的委託和數據源來解決這個問題。它的工作原理,但我想有效地設計。我在同一個'ViewController'中有兩個'UICollectionViews',一個在其單元格中包含UITableViews。我不在收集單元中管理'UITableViews'的原因是因爲響應'UITableViews'中的單元格的選擇和取消選擇,需要在第二個'UICollectionView'中進行更改。知道了,是否仍然可以將代理設置爲'UICollectionViewCell'? – IkegawaTaro

+0

當然。我爲您解決這個問題的一種方式添加了一些額外的解釋。希望它有幫助。 – lintmachine

+0

這是超級有用的。我已經重寫了它,以便'UITableViews'委託和數據源是它們包含在(而不是視圖控制器)中的'UICollectionCell'。我相信我原則上理解你在上面解釋過的代表協議,但實施將肯定證明是一個挑戰。我會讓你知道它是怎麼回事。謝謝。 – IkegawaTaro

相關問題