いくつかの既存のアプリで使用するために、モデル レイヤーの書き直しに取り組んでいます。既存のコードベースは古くなっているので、私のアプローチを一般化して、将来の拡張を容易にし、より最近の言語/テクノロジーの追加 (ARC など) の利点を得たいと考えています。
私の目標は、単純なデータベース レイヤー (FMDatabase の上に構築) と堅牢なモデル オブジェクト クラスで構成される移植可能な、SQL を利用した "フレームワーク" であり、これらが一緒になって複雑さのほとんどをカプセル化します。モデル オブジェクトは、メインのスーパークラスからサブクラス化し、コントラクトに従って、SQL アクションを容易にするために必要なプロパティとスキーマの詳細を提供するメソッドを実装 (およびオーバーライド) します。
私はこのアプローチを使用して PHP で多くの成功を収めましたが、Objective-C で問題が発生しました。
はい、CoreData はこれらのものを提供しますが、いくつかの理由からオプションではありません。実行時に問題を解決するソリューションも見てきましたが、それが ARC で機能するかどうかはわかりません。コンパイルの前にアクセサーを生成することをお勧めします。
私は、マルチスレッド アクセス用のロック ベースのパターンと GCD ベースのアプローチ(ここで提起された質問)を維持するという議論から始め、次のパターンに行き着きました。
- (NSDate *)creationDate {
__block NSDate *aDate;
dispatch_sync(accessorQueue, ^{
aDate = creationDate;
});
return aDate;
}
- (void)setCreationDate:(NSDate *)aDate {
if (![aDate isKindOfClass: [NSDate class]]) {
NSLog(@"setCreationDate: called with non-date object);
return;
}
dispatch_barrier_async(accessorQueue, ^{
if ((!creationDate && aDate) || ![aDate isEqualToDate: creationDate]) {
[self willChangeValueForKey: @"creationDate"];
[changes setObject: aDate ? aDate : [NSNull null]
forKey: @"creationDate"];
creationDate = aDate;
[self didChangeValueForKey: @"creationDate"];
}
});
}
私はそれが好きですが、モデルオブジェクトコードを簡素化するためにプロパティのリストを生成できるようにしたいと考えています. 私の最初のステップは、アクセサー/ミューテーターを構築するためのマクロ展開を作成することです。ここで、私はすでに完璧ではないオプションに出くわしました。
1) マクロでリストを反復処理するのは醜いプロセスです。Boost.preprocessor はオプションかもしれませんが、(2 & 3) を考えるとちょっと怖いです。
2) 使用されるトークンのすべての可能なバージョンでマクロを渡す必要があります (つまり、上記の例のゲッターとセッターの生成を満たすために、作成日と作成日を渡す必要があります)。ショーストッパーではありませんが、理想的ではありません。また。
3) オブジェクト型とプリミティブ型には別のマクロ展開が必要であり、プロパティのリスト (1) の反復処理がさらに困難になります。リスト内の各プロパティに展開マクロを渡すこともできましたが、この「時間の節約」はまったく逆のように見えます。タプルの長いリストは、マクロへの個々の呼び出しのリストよりも読みやすくはありません。
これを可能にする何かを見落としていることを願っています。または、誰かが私が見つけていないドロップインソリューションを既に構築している可能性があります。アクセサーを含むカテゴリを生成するための前処理スクリプトかもしれません...? 私はまだそのオプションを調べていませんが、特にクロスプラットフォームのターゲティングのために他の言語に拡張されている場合は問題ありません.
アドバイスをいただければ幸いです。