2012-02-18 9 views
0

ちょうど私が解決した問題に基づいて、すぐに質問します(好奇心のもの)。My former question

事は、私はカスタムセルオブジェクトが含まれているこののUITableViewを持っていることであるあなたは、このビューに入るたびに、私はこのようのUITableViewのための新しい細胞を生成します。iOS上のARCを使用したメモリ管理

標準的な方法で行わ
if (cell == nil) 
{ 
    [[NSBundle mainBundle] loadNibNamed:@"UploadCellView" owner:self options:nil]; 

    cell = customCell; 
} 

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

問題は、私のカスタムセルオブジェクトがバックグラウンドで起こっているアップロードオブジェクトに関するNSNotificationsをリッスンするので、モデルデータをラベルやプログレスバーなどに更新できるからです。これはカスタムセルのメソッドですオブジェクト):

-(void) uploadProgress: (NSNotification*)notification 
{ 
NSDictionary *userInfo = [notification userInfo]; 

NSNumber *uploadID = [userInfo valueForKey:@"uploadID"]; 

if (uploadID.integerValue == uploadActivity.uploadID) 
{ 
    UIProgressView *theProgressBar = (UIProgressView*)[self viewWithTag:progressBarTag]; 

    [theProgressBar setProgress:(uploadActivity.percentageDone/100) animated:YES]; 

    UILabel *statusText = (UILabel*)[self viewWithTag:percentageTag]; 

    [statusText setText:[NSString stringWithFormat:@"Uploader - %.f%% (%.01fMB ud af %.01fMB)", uploadActivity.percentageDone, uploadActivity.totalMBUploaded, uploadActivity.totalMBToUpload]]; 
} 
} 

彼らは単にこれを行うアップロード仕上げ:彼らは自分の所有しているテーブルビューを呼び出すとき

-(void) uploadFinished: (NSNotification*)notification 
{ 
NSDictionary *userInfo = [notification userInfo]; 

NSNumber *uploadID = [userInfo valueForKey:@"uploadID"]; 

if (uploadID.integerValue == uploadActivity.uploadID) 
{   
    [self setUploadComplete]; 

    [[ApplicationActivities getSharedActivities] markUploadAsFinished:uploadActivity]; 

    NSLog(@"BEGINNING RELOAD"); 
    [parentTable reloadData]; 
    NSLog(@"ENDING RELOAD"); 
} 
} 

今の問題はあるが。テーブルビューが含まれているビューが終了すると、古いカスタムセルオブジェクトはNSNotficationsを取得しているバックグラウンドでまだアクティブです。そのアップロードが完了すると、以前のテーブルビューの古いカスタムセルオブジェクトは、その時点で設定されていたparentTableプロパティをまだ呼び出そうとしています。その結果、ランダムなジャンクメモリが呼び出されます。

ビューは次のように却下されたとき、私はこれを解決方法は、テーブル内に作成し、それらを聞いて停止させるばかりのすべてのセルオブジェクトの配列を保つことでした

-(void) viewWillDisappear:(BOOL)animated 
{ 
    for (UploadCell *aCell in lol) 
    { 
     [aCell stopListening]; 
    } 

    [self.navigationController popViewControllerAnimated:YES]; 
} 

をしかし、これは少しのように思えますハックのビューを閉じたときにカスタムセルオブジェクトが削除されることを確認するにはどうすればよいでしょうか?ビューが再び初期化されると、単に新しいセルが作成されるため、古いセルは使用しません。

カスタムビューセルには、関連するテーブルビューに対する強力なプロパティポインタがありますが、ARCはTableViewポインタが無効にならないことを確認していましたか?明らかにそれは何とかしています。たぶん、含まれているビューがポップ時に削除されるためですか?

答えて

1

セルのようなサウンドは、あなたのUITableViewDataSourceクラスを指し示す保持プロパティを持っています。

代わりにassignプロパティを持つ必要があります。テーブルビューが解放されると、それらは正しく解放されます(セルが保持している場合は現在は表示されません)。彼らはテーブルビューを中退しているとき

また、細胞は、細胞にdidMoveToSuperviewメソッドをオーバーライドし、通知をシャットダウンする必要があります。

彼らは画面をオフにスクロールする場合のように、彼らは更新のリソースを無駄にすることはありません
- (void)didMoveToSuperview 
{ 
    [super didMoveToSuperview]; 
    if ([self superview] == nil) 
    { 
     [self unsubscribeFromYourNotifications]; 
    } 
} 

をもの。

+0

非常に興味深い!私は、セルのビューからUITableViewビューへの参照プロパティを代入して設定し、問題を修正しました!今私が思っているのは、どのようにセルビューがUITableViewを指し示していたのか、あとでもう一度呼び出すときにエラーが発生する可能性がありますか?あたかもランダムなジャンク・メモリを呼び出していたかのように、そのリロード・コールから何か不思議なセレクタ・エラーが発生しました。彼らは強力な保持を持っていれば起こることができないはずですか? – CodingBeagle

+0

細胞が削除されるまで彼らは記憶に残らなければならない?また、didMoveToSuperviewメソッドについてのヒントのおかげで:)そのことは分かりませんでした! – CodingBeagle

+1

あなたが言うように、クラスがメモリ内に留まっていると思っていたのですが、なぜなら、テーブルビュー自体のように、割り当てが解除された他の部分のものでなければ、 (VCはまだテーブル自体が割り当て解除されていてもまだ生きているかもしれません) –

0

uploadIDと通知を受信するセルとの間のマップを保持する個別の更新モデルを検討しましたか?そうすれば、セルはテーブル自体を更新する責任を負いません。更新モデルはそれを行います。テーブルがなくなると、更新モデルをシャットダウンできます。

関連する問題