2010-12-15 12 views
1

tableView:cellForRowAtIndexPath:で日付と時刻の両方をフォーマットする必要があります。 NSDateFormatterの作成はかなり重い操作なので、私は静的にしました。これは、行単位で日付と時刻をフォーマットするための最良の方法ですか?UITableViewセルの日付と時刻の書式設定

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

    static NSString *CellIdentifier = @"Cell"; 
    MyCell*cell = (MyCell*)[self.tableView 
           dequeueReusableCellWithIdentifier:CellIdentifier 
                forIndexPath:indexPath]; 

    static NSDateFormatter *dateFormatter = nil; 
    if (!dateFormatter) 
    { 
     dateFormatter = [[NSDateFormatter alloc] init]; 
     [dateFormatter setLocale:[NSLocale currentLocale]]; 
     [dateFormatter setDateStyle:NSDateFormatterLongStyle]; 
    } 
    cell.dateLabel = [dateFormatter stringFromDate:note.timestamp]; 


    static NSDateFormatter *timeFormatter = nil; 
    if (!timeFormatter) 
    { 
     timeFormatter = [[NSDateFormatter alloc] init]; 
     [timeFormatter setTimeStyle:NSDateFormatterShortStyle]; 
     }  
     cell.timeLabel = [timeFormatter stringFromDate:note.timestamp]; 

return cell; 
} 

答えて

7

私は静的変数を使用しません。なぜなら、ほぼ確実にメモリリークが発生するからです。その代わりに、2つのインスタンス変数またはそのコントローラオブジェクトのプロパティをオンデマンドでのみインスタンス化します。ビューがアンロードされるか、コントローラーの割り当てが解除されると、そのコントローラーを解放できます。例えば

https://github.com/DougFischer/DFDateFormatterFactory#readme

P.S:

@interface MyViewController : UITableViewController { 
    NSDateFormatter *dateFormatter; 
    NSDateFormatter *timeFormatter; 
} 

@end 

@implementation MyViewController 
- (void)viewDidUnload { 
    // release date and time formatters, since the view is no longer in memory 
    [dateFormatter release]; dateFormatter = nil; 
    [timeFormatter release]; timeFormatter = nil; 
    [super viewDidUnload]; 
} 

- (void)dealloc { 
    // release date and time formatters, since this view controller is being 
    // destroyed 
    [dateFormatter release]; dateFormatter = nil; 
    [timeFormatter release]; timeFormatter = nil; 
    [super dealloc]; 
} 

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

    // if a date formatter doesn't exist yet, create it 
    if (!dateFormatter) { 
     dateFormatter = [[NSDateFormatter alloc] init]; 
     [dateFormatter setLocale:[NSLocale currentLocale]]; 
     [dateFormatter setDateStyle:NSDateFormatterLongStyle]; 
    } 

    cell.dateLabel = [dateFormatter stringFromDate:note.timestamp]; 

    // if a time formatter doesn't exist yet, create it 
    if (!timeFormatter) { 
     timeFormatter = [[NSDateFormatter alloc] init]; 
     [timeFormatter setTimeStyle:NSDateFormatterShortStyle]; 
    } 

    cell.timeLabel = [timeFormatter stringFromDate:note.timestamp]; 
    return cell; 
} 

@end 
+1

静的バールを使用するとメモリリークが発生するのはなぜですか?あなたはあなたの提案された解決策を詳しく教えていただけますか?私はあなたのアプローチに本当に従っていません。 – memmons

+0

@ Harkonian静的変数を使用すると、日付フォーマッタを使用し終わった後に日付フォーマッタを解放する方法がないため、メモリリークが発生します。テーブルビューが1回しか見えなくても、残りのアプリケーションライフタイムの間、その日付フォーマッタはぶら下がります。ビューコントローラのサンプルコードを含めるように答えを編集します。 –

+0

私たちが持っていて使いたい変数が参照されているかどうかは、メモリリークそのものです。 – QED

2

私は 場合は、 あなたは静的変数、 を設定する必要がありますNSDateFormatterをたくさん使用していることを様々な場所で読んだが、このメソッドをテストするには、私はそれ を使い切った多くのメモリ。

しかし、あなたのコードでは、フォーマッタに静的変数を使用しません。以下の変更を試してみてください。

static NSDateFormatter *dateFormatter = nil; 
if (!dateFormatter){ 
    dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setLocale:[NSLocale currentLocale]]; 
    [dateFormatter setDateStyle:NSDateFormatterLongStyle]; 
} 
cell.dateLabel = [dateFormatter stringFromDate:note.timestamp]; 
// And same approach for timeFormatter 

(あなたの2つのフォーマッタインスタンスがすべてのランタイムを期間中に手渡すように)これは、メモリを節約することはできませんが、フォーマッタを作成することは重い操作自体はので、このアプローチは、大幅にあなたの方法のパフォーマンスが向上している

0

あなたはNSDateFormatterのの再利用を処理するためにこれを使用することができ、あなたのデータフォーマッタにのみ形式とロケールを設定しているので。