GNU Objective-C ランタイムで、半任意のデータをインスタンス変数にアタッチできますか?
チャレンジ:
私は現在、一種のペット プロジェクトとして、Linux 用の Cocoa に似たものに取り組んでいます。(どうか、「GNUStep を使用する」というすべてのことで脇道にそれないようにしましょう。それについては知っていますが、私のニーズには合いません。先に進みます…) この目的のために、思い起こさせる単純な ORM システムをまとめようとしています。 DBIx::Perl のクラスの。一般的な考え方は、宣言をできるだけ単純に (読み: 短く) することです。また、可能であれば、+(id)constantClassAttribute
オーバーライド用のメソッドを提供する必要はありません。
一般的な考え方は、結果クラスを次のように宣言することです。
@interface SomeTable : ORMResult {
unsigned long long id;
ORMResult *toOneRelation;
ORMResultSet *toManyRelation;
}
@end
これまでのところ、とてもフーピーです。を使用してこれらのフィールドにアクセスできるようになり、や[ORMResult self]->ivars
のようなアクセサーを自動的に生成するなど、あらゆる厄介なことを実行できます。簡単なことです。残念ながら、このセットアップを使用して追加できない情報が 2 つあります。1つは解決するのに十分簡単ですが、もう1つはそれほどではありません。-[toManyRelation]
-[setToOneRelation]
実績クラスとは?
これは、サブクラス化
ORMResult
( などSomeTable
) によって解決され、そこにプラグインされ、ランタイム dynam(ag)ics を使用して to-ness (toMany、toOne) であることがわかります。(そして、これはトリッキーです!) リレーションシップは null 可能ですか?
これは簡単には解決できません。私の最初のアイデアは
(ab) 次のようにプロトコルを使用します。
@interface SomeTable : ORMResult { unsigned long long id; ORMResult <ORMNullable> *toOneRelation; } @end
これはコンパイルされますが、残念ながら、GDB を使用して
ivars->ivar_list
エントリを検査しようとすると、プロトコル情報が実際にはランタイムで操作できるように保持されていないことがわかります。プロトコル宣言は主にコンパイラー向けであるため、これはある種のねじれた意味を持っていると思います。プロトコル識別子 (
byref
、bycopy
および友人、定義を使用して悪用:@interface SomeTable : ORMResult { unsigned long long id; nullable OMRResult *toOneRelation; } @end
これらの指定子は明らかにプロトコルメソッド宣言でのみ機能するため、これには実際には機能しないという明らかな欠点があります。
では、問題は、このイーヴァールへの情報の添付を実際にどのように引き離すことができるかということです。
注:最初に述べたように、Linux 上の GCC によって提供されるGNU Objective-C ランタイムを使用しています。Appleが提供するものではありません!
編集:スターポックス!重要な点を忘れていました。もちろん、別の方法として、単純にすべてのリレーションを null 可能にすることもできます。これは私が本当に望んでいるわけではありませんが、他の選択肢が存在しない場合、それが私がたどり着く道だと思います.