1

UIStepper を含む UITableViewCell サブクラスがあります。ユーザーがステッパーを操作すると、値が 2 秒以内に再度変更されない場合、ステッパーがその値を保存して Core Data に書き込むように、NSTimer を起動します。

別の言い方をすれば:

UIStepper は UITableViewCell に含まれています。
ユーザーはステッパー値を上下に変更できます。
各タッチは、2 秒の遅延でタイマーをトリガーします。
後続の各タッチは、タイマーを無効にします。
ステッパーを 2 秒間放置すると、変更が保存されます。

これは、私が必要としているものに対して非常にうまく機能します。問題は、ユーザーが非常に迅速に値を変更し、View Controller をポップして別の操作を行った場合、2 秒のタイマーがまだ起動しておらず、データが次のアクションに対して最新ではないことです。

できるだけシンプルにするために、(テーブル) ビューがポップされているかどうかをそのテーブル ビュー セル内で判断できるようにする必要があります。その後、保存プロセスを促進し、データが最新であり、他のアクションが実行される前に保存されていることを確認できます。

4

6 に答える 6

1

テーブルがポップされたかどうかを知りたい場合は、クリーンアップ/保存メソッドをメソッドに入れますviewWillDisappear。タイマーを使用しているため、やりたくdeallocないので、意図しない強い参照サイクルはありません。

NSTimerあなたの質問からは明らかではありませんが、あなたが自分のUITableViewCell細胞に負担をかけていないことを確認したいと思います. 明らかに、これはモデルの問題であり、ビューの問題ではありませんが、テーブル ビューはテーブル ビュー セルのデキューと再利用のためにあらゆる種類の最適化を行います。

第二に、データを追跡する必要があるオブジェクト クラス (私はそれを と呼びますModelDataItem) は、保存するメカニズム、タイマーなどを使用するメカニズムだけでなく、保留中のレコードを強制的に保存するメカニズムも提供する必要があります (私はブール値を介して行いますneedSave)。ModelDataItemしたがって、それをサポートするには、少なくとも次の 4 つの項目が必要だと思います。

(a) 独自のタイマーへの参照。

@property (nonatomic, strong) NSTimer *timer;

(b) レコードに保留中の保存操作があるかどうかを示すフラグ

@property (nonatomic) BOOL needSave;

(c) オブジェクトの値が変更されたとき (値がインクリメントされたときなど) に呼び出して、2 秒で保存をスケジュールするメソッド:

- (void)scheduleSave
{
    self.needSave = YES;

    if (self.timer)
        [self.timer invalidate];

    self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0
                                                  target:self
                                                selector:@selector(save)
                                                userInfo:nil
                                                 repeats:NO];
}

(d) タイマーが呼び出して実際にレコードを保存するメソッドが必要です。

- (void)save
{
    // do whatever you need to save the record

    NSLog(@"%s saving value=%@", __FUNCTION__, self.value);

    // now let's clean up the timer

    if (self.timer)
    {
        [self.timer invalidate];
        self.timer = nil;
    }

    self.needSave = NO;
}

次に、テーブル ビュー コントローラーで次のことを行う必要があります。

(a) ステッパーUIControlEventValueChangedが呼び出されたら、明らかにデータ モデルを変更してから、上記のModelDataItemメソッドを呼び出す必要がありscheduleSaveます。

(b) テーブルビューが閉じられているとき、おそらく保留中のものをすぐに保存する必要があります:

for (ModelDataItem *item in allModelDataItems)
{
    if (item.needSave)
        [item save];
}

dealloc最後の点で、保存が必要なモデル アイテムをクリーンアップして保存することにNSTimer依存targetしていないことに注意してくださいdealloc。そのため、手動でそれらを繰り返し処理し、ビューを閉じるときにそれを処理します。

于 2012-11-27T22:00:31.017 に答える
0

過去にこれを行う最良の方法は、UITableViewCellサブクラスをビューコントローラーのデリゲートとして設定することです...次に、ビューコントローラーでviewDidDisappearはデリゲートメソッドを呼び出すだけです。

デリゲートメソッドはUITableViewCellサブクラス内に実装され、2秒のタイマーが完了したときに実行するのと同じコードを呼び出すだけです。これはPhillipが提案した通知方法に似ていますが、代理人の割り当てなどに慣れている場合は少しわかりやすくなります。

于 2012-11-27T17:09:20.073 に答える
0

あなたの説明からはわかりにくいですが、タイマーを使用する必要はまったくないと思います。そのステッパー値をそのクラスのプロパティまたは ivar に割り当ててから、viewDidDisappear メソッドでその値をコア データに書き出すことはできませんか?

于 2012-11-27T16:59:08.973 に答える
0

テーブルビューがなくなるという通知をカスタムセルにリッスンさせ、その通知をviewWillDisappearView Controllerのメソッドに投稿することができます。

于 2012-11-27T15:24:00.563 に答える
0

使用していると思われる NavigationController の親 TableView がポップされると、TableView の割り当てが解除されます。さらに、それぞれの TableViewCells も解放する必要があります。

タイマーを無効にして、保留中の更新を TableViewCell の dealloc メソッド内で処理できます。

デザインを変更せずに、それが私が試みるものです。それが問題であることが判明した場合は、この値が変更されたときに TableView に戻る何らかの通信を設定して、TableView がデータの更新を担当するようにすることもできます。

于 2012-11-27T15:24:08.660 に答える