モーダルビューのプレゼンテーションでも同じようにパフォーマンスが低下していました。パフォーマンスを優先してメモリをいくらか犠牲にすることで、解決策にたどり着きました。
背景:
私のアプリはModel-View-Controller-Storeモデルを使用していました。ストアは私のモデルを処理していたシングルトンだったので、インスタンス化されると、どのクラスからでも実質的にアクセスできました。私はStoreクラスを使用して、プロパティを介して特定の高価なクラス(NSCalendar、NSDateFormatterなど)を回避していました。
解決策:
StoreシングルトンにUIDatePickerプロパティを作成しました。これにより、任意のクラスからアクセスできるようになりました。
シングルトンのインターフェース:
@property (strong, nonatomic) UIDatePicker *datePicker;
シングルトンの実装では、datePickerのゲッターを実装しました。
- (UIDatePicker *)datePicker
{
if (!_datePicker) {
_datePicker = [[UIDatePicker alloc] init];
}
return _datePicker;
}
これにより、datePickerが1回だけ作成され、アプリのどこからでもアクセスできるようになりました。
ここで、ピッカーを使用する必要があるクラスのviewDidLoadメソッドで、getterメソッドを介してプロパティを取得します。
UIDatePicker *aDatePicker = [[MySingleton shareInstance] datePicker];
// Set it's location.
[aDatePicker setFrame:CGRectMake(0.0, 236.0, self.view.frame.size.width, 216.0)];
// Connect to any actions
[aDatePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
// Add it to you view
[self.view addSubview:[[MySingleton shareInstance] datePicker]];
日付ピッカーが作成されているときに、動作が遅くなります。1回おきに、モーダルビューが非常に高速に表示されます(ビューに他に何があったかによって異なります)。
基本的に、私はグローバル変数を作成し、それを維持して、メモリを犠牲にして毎回作成する必要がないようにしました。私のアプリの場合、パフォーマンスの違いはそれを価値のあるものにしました。
注:
ただし、注意すべき点が1つあります。datePickerはモーダルビューよりも長持ちする可能性が高いため、datePickerが割り当て解除されたメモリを指していないことを確認する必要があります。
したがって、viewDidLoadで「self」がターゲットとして割り当てられた場合:
[aDatePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
viewDidDisappearなどのメソッドで、クラッシュを防ぐためにこのコードを追加することが重要です。
[aDatePicker removeTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];