1

いくつかの既存のアプリで使用するために、モデル レイヤーの書き直しに取り組んでいます。既存のコードベースは古くなっているので、私のアプローチを一般化して、将来の拡張を容易にし、より最近の言語/テクノロジーの追加 (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) の反復処理がさらに困難になります。リスト内の各プロパティに展開マクロを渡すこともできましたが、この「時間の節約」はまったく逆のように見えます。タプルの長いリストは、マクロへの個々の呼び出しのリストよりも読みやすくはありません。

これを可能にする何かを見落としていることを願っています。または、誰かが私が見つけていないドロップインソリューションを既に構築している可能性があります。アクセサーを含むカテゴリを生成するための前処理スクリプトかもしれません...? 私はまだそのオプションを調べていませんが、特にクロスプラットフォームのターゲティングのために他の言語に拡張されている場合は問題ありません.

アドバイスをいただければ幸いです。

4

1 に答える 1

0

最終的に、モデル オブジェクト ヘッダー ファイルのプロパティ宣言を調べて、各クラスの新しいカテゴリにカスタム アクセサーを書き出す Python スクリプトを作成しました。これを容易にするために、次の形式のコメント文字列でプロパティ宣言に注釈を付けます。

// SqlFieldName SqlFieldType

また、オブジェクト アクセサーとプリミティブ アクセサーの基本的なテンプレートをいくつか定義しました。

結果は非常に実装固有ですが、検索/置換中の名前変更の見落としにより、通常は少なくとも 1 つのバグの原因となるアクセサーのコピー/貼り付け/検索/置換作業を大幅に節約できます。

カテゴリを使用してアクセサーを格納すると、カテゴリ内のオブジェクト メソッドをオーバーライドするためのコンパイル警告が表示されますが、-Wobjc-protocol-method-implementation を使用してそれらを黙らせることができます。

生成されたコードは私のニーズに非常に固有のものですが、興味がある人は投稿します。

于 2013-04-14T17:01:38.823 に答える