So I try to compile some older code (10.5) on SnowLeopard and I get:
error: @defs is not supported in new abi
The offending code looks something like this
@interface Foo
{
void *table1_;
}
@endif
static inline BOOL Foo_IsASpecialObject( Foo *self, id p)
{
return( NSHashGet( ((struct { @defs( Foo) } *) self)->table1_, p) != nil);
}
If you find this a little obscure, I once wrote an article about it (look for Using inline functions instead of method calls)
These are all the solutions to this particular problem I came up with:
- don't use the new ABI / abandon platform
- pester ABI maintainer to support @defs
- pester ABI maintainer to support static inline between @interface and @end
- painstakingly create a shadow struct, that mimics the Foo class
- unprotect inline accessed instance variables in Foo with @public
Comments (2)
#2 and #4 are simply not valid in the non-fragile runtime. Even if you have complete control of the class hierarchy, with a custom root class, the layout of your objects may change between system releases, or in principle, between runs of your app. You could use a dynamic ivar offset set in, say, +initialize, but then you’ve got to load a global each time the function is called.
#3 strikes me as reasonable, and filing a feature request won’t hurt. The ObjC guys aren’t entirely sealed within an ivory tower.
#5 is as clean as mucking about with objects using functions in the first place, so I don’t really see the problem. If you want it clean and encapsulated, use methods™.
Posted by Ahruman
|
November 14, 2009 11:59 AM
Posted on November 14, 2009 11:59
I think at some time I'd like to discuss the benefits of a non-fragile runtime, but that'd be lengthy and not for today.
As to point #5, I think it's actually worse, if I expose the instance variable via @public. With the function I remain in control. For example I can still be sure, that a dependent variable is also updated.
Or in bigger words using @public adds more to the complexity of the code than using @defs.
I am experimenting with a scheme like this at the moment (when the inline functions are used internally only), where I set FOO_IVAR_VISIBILITY to @public at opportune moments...
@interface Foo : NSObject
{
#ifdef FOO_IVAR_VISIBILITY
FOO_IVAR_VISIBILITY
#endif
It don't really like it, though the inline functions code is now much simpler.
Posted by Nat!
|
November 14, 2009 2:27 PM
Posted on November 14, 2009 14:27