Re: Classes incompatible with weak references
Re: Classes incompatible with weak references
- Subject: Re: Classes incompatible with weak references
- From: John McCall <email@hidden>
- Date: Mon, 13 Aug 2012 10:54:24 -0700
On Aug 13, 2012, at 9:29 AM, Jean-Daniel Dupas wrote:
> Le 13 août 2012 à 17:56, Kyle Sluder <email@hidden> a écrit :
>> On Aug 13, 2012, at 8:42 AM, Ben <email@hidden> wrote:
>>
>>> I see in the documentation - and from a compiler error - that some classes are not compatible with weak references.
>>>
>>> What makes these classes incompatible?
>>
>> They have custom implementations of -retain and -release.
>>
>> When NextSTEP was first released, there was no refcounting, just +new and +free. That's why NSObject (actually Object at the time) has only one ivar: isa, a pointer to the object's class.
>>
>> Some time later -retain and -release came into being, but the storage for refcount couldn't be added to Object because of the fragile base class problem—all existing code expected sizeof(Object)==sizeof(id), so they hardcoded offsets for accessing subclass ivars.
>
> I don't get it. retain/release has been introduced by NSObject.
> As all classed that use ref counting are based on NSObject and not Object, it was perfectly possible to declare 2 ivars in NSObject without breaking anything when it was first introduced.
In the so-called "fragile" ABI, which is what you get on PPC, PPC64, and i386, class layout is performed at compile time, and the machine code pattern for accessing an ivar is the same as accessing a struct member: the compiler knows that 'int count;' is at offset 32 (say), so it just adds 32 to the base pointer value to find the address of the ivar. This is why all ivars have to be declared in the main @interface when compiling for these platforms: it would otherwise be impossible to do class layout for subclasses. Adding an ivar to a class would change that layout, causing all code with class layouts or ivar accesses compiled against the existing layout to stop working.
There were releases made with NSObject having no ivars (except 'isa'). Therefore adding new ivars would have broken binary compatibility with those releases.
In theory, we could have introduced refcount ivars at any of the natural binary-compatibility breaks that happened after refcounting became pervasive, like moving to i386. I'm not privy to all the rationale for why we didn't, but I assume that at least part of it was not wanting to increase the porting burden in case someone was relying on the size of NSObject. I know that there are some very tightly-optimized object layouts out there. These aren't impossible hurdles to clear, but they're a lot of extra effort.
Even in modern ABIs, like those on ARM and x86-64, we are aware of code that still assumes that NSObject, at least, has a fixed layout. We don't *promise* anything about that layout, but that never stopped anyone from depending on it before.
John.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden