0

解決したばかりの問題に基づいて、すぐに質問してください(好奇心の問題です)(問題への回答を投稿に投稿します。これはここにあります:私の以前の質問問題

は、私がこのUITableViewを持っていることですカスタム セル オブジェクトが含まれています。このビューに入るたびに、次のように UITableView の新しいセルを生成します。

    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ポインターが無効にならないようにすると思いましたか? 明らかにそれはどういうわけかです。たぶん、ポップされたときに含まれているビューが削除されたためでしょうか?

4

2 に答える 2

1

セルには UITableViewDataSource クラスを指す保持プロパティがあるようです。

代わりに割り当てプロパティが必要です。そうすれば、テーブル ビューが解放されたときに適切に解放されます (現在、セルがそれを保持している場合は解放されません)。

また、cellsdidMoveToSuperviewメソッドをオーバーライドして、セルがテーブルビューから削除されたときに通知をシャットダウンする必要があります。

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];
    if ( [self superview] == nil )
    {
        [self unsubscribeFromYourNotifications];
    }
}

つまり、画面をスクロールしても、リソースを無駄に更新することはありません。

于 2012-02-18T03:59:47.787 に答える
0

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

于 2012-02-18T03:43:46.817 に答える