2012-10-18 16 views
0

我正在開發iOS的選項卡式應用程序(5向上)。 在3個選項卡中的2個之間進行了幾次切換後,我的應用程序在模擬器中遇到了崩潰,這兩個選項卡都包含表格(以及其他一些 - 這裏可能不是相關的東西)。以下是單元格創建和錯誤代碼的重要部分。UITableViewCellAccessibilityElement版本崩潰在選項卡切換

的失事(每次不同)變化的數量後,會發生,而且總是訪問標籤2.

注意我使用ARC時。

* UPDATE *該問題只在iOS 6出現以前的版本不affected.it可能是依賴於被調用一些線程代碼,如下所示:

if (!self.progressBackground) { 
     self.progressBackground = [[UIView alloc]initWithFrame:CGRectMake(100, 260, 120, 120)]; 
     [self.progressBackground setBackgroundColor:[UIColor blackColor]]; 
     [[self.progressBackground layer]setCornerRadius:15]; 
     UILabel *progressText = [[UILabel alloc]initWithFrame:CGRectMake(0, 80, 120, 30)]; 
     UIFont *fontName = [UIFont fontWithName:@"Helvetica" size:14.0]; 
     [progressText setFont:fontName]; 
     [progressText setText:@"Updating Tags"]; 
     [progressText setTextColor:[UIColor whiteColor]]; 
     [progressText setTextAlignment:UITextAlignmentCenter]; 
     [progressText setBackgroundColor:[UIColor clearColor]]; 
     [self.progressBackground addSubview:progressText]; 
     [self.progressBackground setAlpha:.6];     
    } 
    if (!self.progressView) { 
     self.progressView = [[UIActivityIndicatorView alloc]initWithFrame:self.progressBackground.frame]; 
     [self.progressView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    } 
    [self.view addSubview:self.progressBackground]; 
    [self.view addSubview:self.progressView]; 
    [self.progressView startAnimating]; 

    [NSThread detachNewThreadSelector:@selector(initializeCategoriesArray) toTarget:self withObject:nil]; 

和方法'initializeCategoriesArray' 看起來像這樣:

-(void)initializeCategoriesArray{ 

if (!self.categoryArchive) { 
    self.categoryArchive = [[NSMutableArray alloc]init]; 
} 

//set the right month' expenses 
self.currentMonthExpenses = (NSMutableArray*)[self.dataHandler fetchAllExpensesForMonth:[NSNumber numberWithInteger:self.currentMonthNumber ]]; 


// check if expenses exist at all 

if (self.currentMonthExpenses.count == 0) { 
    [self.categoryArchive removeAllObjects]; 
    [self.categoriesTable reloadData]; 
    [self.progressView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES]; 
    [self.progressView performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; 
    [self.progressBackground performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; 
    return; 
} 



// sort out month Expenses 
NSMutableArray *dayTypeExpenses = [[NSMutableArray alloc]init]; 
for (Expense *exp in self.currentMonthExpenses) { 
    if (exp.expenseType.boolValue == NO) { 
     [dayTypeExpenses addObject:exp]; 
    } 
} 


// check if dayExpenses exist 
if (dayTypeExpenses.count == 0) { 
    [self.categoryArchive removeAllObjects]; 
    [self.categoriesTable reloadData]; 
    [self.progressView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES]; 
    [self.progressView performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; 
    [self.progressBackground performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; 
    return; 
} 

// create Dictionary holding all DayExpenses under their STRING AS KEY 
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc]init]; 
for (Expense *exp in dayTypeExpenses) { 

    NSMutableArray *temp = [tempDict objectForKey:exp.name]; 
    if (temp == nil) { 
     NSMutableArray *tempArray = [[NSMutableArray alloc]init]; 
     [tempDict setValue:tempArray forKey:exp.name]; 
    } 
    [[tempDict objectForKey:exp.name]addObject:exp]; 
} 

// create temporary (unsorted) array of Categories 
NSMutableArray *tempCatArray = [[NSMutableArray alloc]init]; 
for (NSMutableArray *expArray in [tempDict allValues]) { 
    double totValue = 0; 
    NSInteger count = 0; 
    double average = 0; 
    CGFloat percentage = 0; 
    for (Expense* exp in expArray) { 
     count++; 
     totValue = totValue+exp.value.doubleValue; 
    } 
    average = totValue/count; 
    percentage = totValue/self.spentCurrentMonth; 
    Category *newCategory = [[Category alloc]init]; 
    [newCategory setTotalValue:totValue]; 
    [newCategory setName:[[expArray objectAtIndex:0]name]]; 
    [newCategory setNumberOfExpenses:count]; 
    [newCategory setAverageValue:average]; 
    [newCategory setPercentOfBudgetInFloat:fabs(percentage)]; 

    [tempCatArray addObject:newCategory]; 
} 

// sort tempArray 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"totalValue" ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; 
self.categoryArchive = [[tempCatArray sortedArrayUsingDescriptors:sortDescriptors]mutableCopy]; 

// find normfactor 


CGFloat normFactor = fabs(1.0/[[self.categoryArchive objectAtIndex:0] percentOfBudgetInFloat]); 

for (Category *cat in self.categoryArchive) { 
    if (cat.name.length == 0) { 
     cat.name = @"Uncategorized"; 
    } 
    if (cat.percentOfBudgetInFloat >= 1) { 
     cat.percentOfBudgetInFloat = 1; 
    } 
    cat.percentOfBudgetInFloat = cat.percentOfBudgetInFloat*normFactor; 
} 


// reload 
[self.categoriesTable reloadData]; 

[self.progressView performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES]; 
[self.progressView performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; 
[self.progressBackground performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; 

} 

表1:

TableView, each cell contains 2 labels 1 button 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
static NSString *CellIdentifier = @"dayCell";  
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) { 
    UIFont *subjectFont = [UIFont fontWithName:@"Helvetica" size:14.0]; 
    UIFont *valueFont = [UIFont fontWithName:@"Helvetica-Bold" size:14.0]; 

    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; 
    [cell.textLabel removeFromSuperview]; 


    // Cell Look 
    UIImageView *backgroundImg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"cell" ]]; 
    [cell setBackgroundView:backgroundImg]; 

    // Subjectlabel 
    UILabel *subjectLabel = [[UILabel alloc]initWithFrame:CGRectMake(30, 15, 160, 20)]; 
    //... 

    // ValueLabel 
    UILabel *valueLabel = [[UILabel alloc]initWithFrame:CGRectMake(160, 15, 90, 20)]; 
    //... 


    // Deletion Button 
    UIButton *delButton = [[UIButton alloc]initWithFrame:CGRectMake(255, 0, 50, 50)]; 
    [delButton setBackgroundColor:[UIColor clearColor]]; 
    [delButton setImage:[UIImage imageNamed:@"delButt" ] forState:UIControlStateNormal ]; 
    delButton.tag = 1002; 
    [cell addSubview:delButton]; 
} 
//... 

UIButton *delButton = (UIButton*)[cell viewWithTag:1002]; 
[delButton addTarget:self action:@selector(deleteRow:) forControlEvents:UIControlEventTouchUpInside]; 

//... 
return cell; 
} 

表2:

TableView, each cell contains 2 labels, 1 rectangular UIView 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
static NSString *CellIdentifier = @"thisMonthCell"; 


UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) { 
    UIFont *subjectFont = [UIFont fontWithName:@"Helvetica" size:14.0]; 
    UIFont *valueFont = [UIFont fontWithName:@"Helvetica-Bold" size:16.0]; 

    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; 
    [cell.textLabel removeFromSuperview]; 

    // BarGraph for this Cell 
    UIView *barProgress = [[UIView alloc]initWithFrame:CGRectMake(20, 1, 1, 37)]; 
    [barProgress setBackgroundColor:[self goldBarColor]]; 
    [barProgress setAlpha:.5]; 
    barProgress.tag = 1000; 
    [cell addSubview:barProgress]; 



} 

Category *cellCategory = [self.categoryArchive objectAtIndex:indexPath.row]; 

UIView *progressBar = (UIView *)[cell viewWithTag:1000]; 
[progressBar setFrame:CGRectMake(progressBar.frame.origin.x, progressBar.frame.origin.y, cellCategory.percentOfBudgetInFloat*280, progressBar.frame.size.height)]; 

//... 


return cell; 

} 

在崩潰錯誤代碼讀取這樣的:

2012年10月18日14:57:13.218的每日預算乘以[4714 :c07] * - [UITableViewCellAccessibilityElement發佈]:發送消息發送位於實例0x7571630 dlopen(/Applications/Xcode.app/Contents/PlugIns/DebuggerFoundation.ideplugin/Contents/Resources/DebuggerIntrospectionSupport.dylib,0x00000002) dyld:loaded:/Applications/Xcode.app/Contents/PlugIns/DebuggerFoundation.ideplugin /Contents/Resources/DebuggerIntrospectionSupport.dylib


的問題出現在模擬器只,不是一個真正的設備上(不論是iOS 6.0)

任何想法的問題可能是?

回答

2

編輯:

實際問題,更新界面關閉主線程。詳細閱讀評論。

---原來的答案---

我會建議你使用一個自定義單元格,而不是試圖以編程方式改變蘋果tableviewcell內置。該文檔有一些很好的例子來說明如何做到這一點。如果你有一個故事板,這很容易。

我的猜測會發生在你所迷惑的tableview單元格的對象(文本標籤 - 附件視圖連接)中的預期保留計數中,並且arc沒有捕獲到你的removeFromSuperview魔法。

+0

這不是問題,似乎遺留線程代碼使它跳躍,我刪除了backgroundthread,並在主線程中進行計算 - 獎勵仍然是因爲我不知道爲什麼這是一個問題;) –

+0

所有的UI代碼需要在主線程上完成。對不起,我錯過了。 –

+0

它只是一行[_tableView reloadData],所以這是唯一的問題? –

0

UIKit可能試圖發佈一些內部未預期需要發佈的內容。嘗試在兩個實現中註釋掉[cell.textLabel removeFromSuperview];,並用cell.textLabel.hidden = YES替換它,這可能很好地阻止了這次崩潰。

+0

感謝您的輸入,可悲的是這並沒有解決問題:( –