2011-05-12 29 views
2

私は友達のバンドのために独自のアプリケーションを作成しようとしていましたが、ウェブサイトに表示されるニュース記事のカスタムTableViewCellを試してみました。私の主な目的は、Webサイトからすべてのデータを取得し、それをNSMutableArrayに格納し、それを自分のカスタムセルに表示することです。スクロール時にUITableViewがクラッシュする

最初の5-6セルが読み込まれるとアプリは正常に動作します。しかし、私がスクロールを開始すると、アプリケーションがクラッシュします。私はcellForRowAtIndexPath:メソッドでそれを特定しました。 GDBを使用して、NSMutableArrayデータを作成した後、プログラムを実行した後、スクロールした後、配列がオートリリースされているように見えます。なぜこのようなことが起こるのか分かりません。 HomeViewController.hで

:ここで私はこれまでの私のコードのために持っているものだ

HomeViewController.mで
@interface HomeViewController : UIViewController { 
    NSArray *results; 
    NSMutableArray *titles; 
    NSMutableArray *dates; 
    NSMutableArray *entries; 
} 

@property (nonatomic, retain) NSMutableArray *titles; 
@property (nonatomic, retain) NSMutableArray *dates; 
@property (nonatomic, retain) NSMutableArray *entries; 

@end 

:ここ

- (void)viewDidLoad { 
[super viewDidLoad]; 
titles = [[NSMutableArray alloc] init]; 
dates = [[NSMutableArray alloc] init]; 
entries = [[NSMutableArray alloc] init]; 

while((i+1) != endIndex){ 
    NSString *curr_title = [[NSString alloc] init]; 
    NSString *curr_date = [[NSString alloc] init]; 
    NSString *curr_entry = [[NSString alloc] init]; 

    //do some character iterations across a string 

    [titles addObject:curr_title]; 
    [dates addObject:curr_date]; 
    [entries addObject:curr_entry]; 

    [curr_title release]; 
    [curr_date release]; 
    [curr_entry release]; 
} 
} 

//より多くのコードは、

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

static NSString *CellIdentifier = @"NewsCell"; 


NewsCell *cell = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) { 
    NSArray *topLevelObjects = [[NSBundle mainBundle] 
           loadNibNamed:@"NewsCell" 
           owner:self options:nil]; 
// cell = [topLevelObjects objectAtIndex:0]; 
    for(id currentObject in topLevelObjects){ 
     if([currentObject isKindOfClass:[UITableViewCell class]]){ 
      cell = (NewsCell *)currentObject; 
      break; 
     } 
    } 

} 
NSLog(@"%d", indexPath.row); 
NSLog(@"%d", titles.count); 
cell.cellTitle.text = [titles objectAtIndex:indexPath.row]; 
cell.datePosted.text = [dates objectAtIndex:indexPath.row]; 
cell.preview.text = [entries objectAtIndex:indexPath.row]; 

return cell; 
} 
を削除しました

再び、最初の5-6細胞が現れる。私はスクロールしたら、私はpo titlesをやってみましたし、このエラーを得た:

Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000009 0x011b309b in objc_msgSend()

私はinitWithNibName:で配列を割り当てる試みたが、それは多くを行うようには見えませんでした。私はviewDidLoad:のすべてのコードを移動してから[super viewDidLoad]を呼び出してみましたが、同じ結果が得られました。申し訳ありませんが、これは長すぎますが、私は人々が自分のコードを見る必要があると考えました。

答えて

2

投稿したコードに間違いはありません。試してくださいenabling the NSZombieEnabled environment variable。これにより、オブジェクトが解放されるのを防ぐので、アプリケーションがクラッシュしたときに問題の原因となったオブジェクトを特定できます。

また、loadNibNamed:owner:optionsが返すオブジェクトの配列をループする代わりに、クラスのIBOutletプロパティに目的のオブジェクトを割り当てる必要があります。例については、Loading Custom Table-View Cells From Nib Filesを参照してください。


次はあなたが投稿新しいコードから抽出された:(NSMutableStringのように)

NSString *curr_title = [[NSString alloc] init]; 

//do some character iterations across a string 

[titles addObject:curr_title]; 

[curr_title release]; 

NSStringのは変更できません。意図的に空の文字列をtitles配列に追加していますか?あなたのコメントを受けて


stringByAppendingStringは、新しい自動解放のNSStringオブジェクトを作成します。

NSString *curr_title = [[NSString alloc] init]; 

// this leaks the original NSString object (curr_title no longer points to it); 
// curr_title now points to a new, autoreleased NSString 
curr_title = [curr_title stringByAppendingString:@"..."]; 

[titles addObject:curr_title]; 

// releasing the autoreleased NSString will cause your application to crash! 
[curr_title release]; 
+0

迅速な対応をありがとう!私はNSZombiesEnabledを使ってみましたが、奇妙なことに何の情報も提供していませんでした。インストゥルメントを使用し、「Objective-Cメッセージがアドレス0x5e70870の割り当て解除されたオブジェクト(ゾンビ)に送信されました」と言いました。それは自動リリースされたものを指していたので、私は現在それを調べています。私の配列は何とか解放されているようです。 – SpacePyro

+0

また、配列に追加しているオブジェクトが過剰にリリースされていないことを確認してください。 – titaniumdecoy

+0

私はいくつかのコードを追加しました(上記の編集)。私は彼らが過剰にリリースされているとは思わないが、どういうわけか彼らは(私はまだObjective-cのハングを取得しようとしている!)、私は間違いなくそれを修正します。 – SpacePyro

0

問題は、すべてのあなたの特性が保持され、NewsCellの実装であるかもしれませんか?

さらに、HomeViewControllerはUITableViewControllerではなくUIViewControllerをサブクラス化していますか?

そして、これがうまく動作するはずです:

NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewsCell" owner:self options:nil]; 
cell = [topLevelObjects objectAtIndex:0]; 
+1

これらのアレイは過度に保持されていません。合成された設定メソッドは使用されていません。 – Leehro

+0

UITableViewControllerをサブクラス化してUIViewController内のUITableViewを使用する必要はありません。 UITableViewControllerは便利ですが、柔軟性に欠けます。 – titaniumdecoy

+0

ニースキャッチ;あなたが私の投稿にコメントするつもりだと思います。一定! – titaniumdecoy

0

* EXC_BAD_ACCESS *あなたのオブジェクトのいずれかが解放さを乗り越えている(または適切に保持されなかった)ことを確認してくださいサインがあります。 NSZombieEnabledは、titaniumdecoyが示唆しているのと同じように、ここにあなたの友人です - どのオブジェクトがリリースされているかを把握することは、戦闘の半分です。アプリをリリースする前に、必ずオフにしてください。(titaniumdecoyが指摘するように)オブジェクトが解放されるのを防ぐためです。

私は通常、NSZombieEnabledとよく配置されたブレークポイントの組み合わせを使用します(コードが破損するまでコードを歩き回ることができるので)。それから、オブジェクトがどこに公開されたのかを把握するのは、通常、バックトラックの単純な問題です。

関連する問題