我可以在 GNU Objective-C 运行时中将半任意数据片段附加到实例变量吗?
挑战:
我目前正在研究一种类似于 Linux 的 Cocoa,作为一种宠物项目。(拜托,我们不要被所有“使用 GNUStep”的东西所牵制。我知道,但它不适合我的需要。继续……)为此,我试图拼凑一个简单的 ORM 系统,让人想起Perl 的 DBIx::Class。一般的想法是使声明尽可能简单(阅读:简短),并且如果可能的话,不需要提供+(id)constantClassAttribute
覆盖方法。
一般的想法是声明我的结果类如下:
@interface SomeTable : ORMResult {
unsigned long long id;
ORMResult *toOneRelation;
ORMResultSet *toManyRelation;
}
@end
到目前为止,太棒了。我现在可以使用 访问这些字段[ORMResult self]->ivars
,并做各种讨厌的事情,比如自动生成访问器,如-[toManyRelation]
or -[setToOneRelation]
。小菜一碟。不幸的是,我无法使用此设置添加两条信息;一个很容易解决,另一个不太简单:
实际结果类是什么?
这可以通过子类化
ORMResult
(如SomeTable
)解决,并将其插入其中,使用运行时动态(ag)ics 来确定它的一致性(toMany,toOne)。(这是一个棘手的问题!)这种关系可以为空吗?
这不太容易解决。我最初的想法是
(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
这有一个相当明显的缺点,即实际上不起作用,因为这些说明符显然只在协议方法声明中起作用。
那么,问题是如何在实践中消除这种对 ivars 的信息附加?
注意:正如最初提到的,我使用的是GNU Objective-C 运行时,由 Linux 上的 GCC 提供;而不是苹果提供的!
编辑:星痘!我忘记了一个中心点:当然,另一种选择是简单地使所有关系都可以为空。这我真的不想要,但如果没有其他选择存在,我想这就是我最终要走的路。