Note that there are some explanatory texts on larger screens.

plurals
  1. POGNU Objective-C runtime trickery
    text
    copied!<p>Can I, in the GNU Objective-C runtime, attach semi-arbitrary pieces of data to instance variables?</p> <h3>Challenge:</h3> <p>I'm currently working on a kind of Cocoa workalike for Linux, as a sort of pet project. (Please, let's not get sidetracked by all the "use GNUStep" stuff. I know about it, but it doesn't suit my needs. Moving on…) For this purpose I'm trying to cobble together a simple ORM system, reminiscent of DBIx::Class for Perl. The general idea is to make the declaration as simple (read: short) as possible, and if at all possible, without the need to provide <code>+(id)constantClassAttribute</code> methods for overriding.</p> <p>The general idea is to declare my result classes as follows:</p> <pre><code>@interface SomeTable : ORMResult { unsigned long long id; ORMResult *toOneRelation; ORMResultSet *toManyRelation; } @end </code></pre> <p>So far, so hoopy. I can now access these fields using <code>[ORMResult self]-&gt;ivars</code>, and do all manner of nasty stuff, like automagically generating accessors like <code>-[toManyRelation]</code> or <code>-[setToOneRelation]</code>. Piece of cake. Unfortunately, there are two pieces of information I cannot add using this setup; one is simple enough to solve, the other not so much:</p> <ol> <li><p>What is the actual result class?</p> <p>This is solved by subclassing <code>ORMResult</code> (like <code>SomeTable</code>), and plugging that in there, using runtime dynam(ag)ics to figure out it's to-ness (toMany, toOne).</p></li> <li><p>(And this is the tricky one!) Is the relationship nullable?</p> <p>This is less easily solved. My initial ideas were</p> <ol> <li><p>(ab)using protocols, like so:</p> <pre><code>@interface SomeTable : ORMResult { unsigned long long id; ORMResult &lt;ORMNullable&gt; *toOneRelation; } @end </code></pre> <p>This compiles, but unfortunately, when I try to use GDB to inspect the <code>ivars-&gt;ivar_list</code> entries I find that the protocol information isn't actually kept for the runtime to toy with. This makes, I suppose, some kind of twisted sense, as protocol declarations are mostly for the compiler.</p></li> <li><p>Abusing the protocol identifiers (<code>byref</code>, <code>bycopy</code> and friends, using defines:</p> <pre><code>@interface SomeTable : ORMResult { unsigned long long id; nullable OMRResult *toOneRelation; } @end </code></pre> <p>This has the rather obvious drawback of not actually working, as these specifiers apparently only work in protocol method declarations.</p></li> </ol></li> </ol> <p>The question, then, is how can this attachment of information to the ivars be pulled off in practice?</p> <p><strong>Note:</strong> As mentioned initially, I'm using the <em>GNU Objective-C runtime</em>, as supplied by GCC on Linux; and <em>not the one supplied by Apple!</em></p> <p><strong>Edit:</strong> Starpox! I forgot a central point: An alternative, of course, is to simply make <em>all</em> relations nullable. This I don't really want, but if no other alternative exists, I guess that's the path I'll end up going down.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload