0

iOS(5以上)用のタブ付きアプリケーションを開発しています。私のアプリは、3 つのタブのうちの 2 つをいくつか切り替えた後、シミュレーターでクラッシュを経験しています。どちらにもテーブルが含まれています (および他のいくつか - ここではおそらく関係のないもの)。以下は、セル作成の重要な部分とエラー コードです。

クラッシュは、(毎回異なる) 数の変更の後、常にタブ 2 にアクセスするときに発生します。

私はARCを使用しています。

* 更新*この問題は iOS 6 でのみ発生します。以前のバージョンは影響を受けません。呼び出されるスレッド コードに依存している可能性があり、次のようになります。

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 DailyBudget[4714:c07] * -[UITableViewCellAccessibilityElement release]: 割り当て解除されたインスタンス 0x7571630 dlopen(/Applications/Xcode.app/Contents/PlugIns/DebuggerFoundation.ideplugin/Contents/Resources/ DebuggerIntrospectionSupport.dylib、0x00000002) dyld: ロード済み: /Applications/Xcode.app/Contents/PlugIns/DebuggerFoundation.ideplugin/Contents/Resources/DebuggerIntrospectionSupport.dylib


問題はシミュレーターでのみ発生し、実際のデバイスでは発生しません (両方とも iOS 6.0)

問題が何であるかについてのアイデアはありますか?

4

2 に答える 2

2

編集:

実際の問題は、メイン スレッドから UI を更新することでした。詳細についてはコメントをお読みください。

--- 元の回答 ---

組み込みの Apple テーブルビューセルをプログラムで変更するのではなく、カスタム セルを使用することをお勧めします。ドキュメントには、これを行う方法に関するいくつかの良い例があります。ストーリーボードがあれば、とても簡単です。

私の推測では、テーブルビュー セルのオブジェクト (テキスト ラベル - アクセサリ ビュー接続) で予想される保持カウントで何かが起こっており、アークが removeFromSuperview マジックをキャッチしていない可能性があります。

于 2012-10-22T15:53:22.690 に答える
0

UIKit は、内部的にリリースする必要があるとは予想していない何かをリリースしようとしている可能性があります。両方の実装でコメントアウトして[cell.textLabel removeFromSuperview];置き換えてみてください。これによりcell.textLabel.hidden = YES、このクラッシュが停止する可能性があります。

于 2012-10-18T19:30:48.070 に答える