discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Why is +initialize not inherited?


From: Larry Campbell
Subject: Re: Why is +initialize not inherited?
Date: Thu, 15 Sep 2011 14:46:53 -0400

I always thought it was a bad idea to call +initialize directly. For one thing, 
the runtime guarantees that only one thread can be in your +initialize at a 
time, but that guarantee vanishes if you call it yourself directly. So I 
typically (on Mac OS) try to init classes like this as follows:

    [Subclass class];

On Mac OS X that causes +[Superclass initialize] to get called, but not in 
gnustep.

- lc

On Sep 15, 2011, at 2:43 PM, David Chisnall wrote:

> I'm not sure how that would help you.  Your subclasses would only receive a 
> +initialize message once you'd sent them some other message, which requires 
> some other bit of code to be able to locate them, which means the other code 
> can trivially register them...
> 
> That said, I agree that we should aim to be compatible with Apple, although 
> in this case I think the GNU behaviour is more logical.  I've made that 
> change in the GNUstep Objective-C runtime, and it will be part of the 1.6 
> release unless someone objects strongly...
> 
> David
> 
> On 15 Sep 2011, at 19:28, Larry Campbell wrote:
> 
>> The problem I have is when some shared behavior is implemented in a 
>> superclass, and it doesn't get called for the subclass. Something like:
>> 
>> @implementation Superclass
>> + (void)initialize
>> {
>>   [OtherClass registerNewClass:self];
>> }
>> @end
>> 
>> Now if I subclass Superclass, my subclass doesn't get registered, unless I 
>> explicitly call +[Subclass initialize] myself. But I don't think I should 
>> have to call initialize myself; the runtime should do it for me.
>> 
>> - lc
>> 
>> 
>> 
>> On Sep 15, 2011, at 12:01 PM, Fred Kiefer wrote:
>> 
>>> I have to apologize, sticking to these simple rules isn't as easy as I 
>>> thought it would be. I just fixed a bug in Gorm that was inside of an 
>>> +initialize method in a category. Just imagine somebody had implemented 
>>> that method in the main class later on.
>>> 
>>> On 14.09.2011 23:39, Fred Kiefer wrote:
>>>> What exactly was the problem that you experienced?
>>>> In GNUstep we always write our +initialize methods like this and I don't
>>>> know of any problem with that style:
>>>> 
>>>> + (void)initialize
>>>> {
>>>> if (self == [MyClass class])
>>>> {
>>>> // do stuff
>>>> }
>>>> }
>>>> 
>>>> There are certain differences between the different runtimes, but in
>>>> most cases you are save to ignore them as long as you stick to a careful
>>>> coding style.
>>>> 
>>>> On 14.09.2011 23:09, Larry Campbell wrote:
>>>>> Today, having forgotten this five-year-old conversation, I was burned
>>>>> by this again.
>>>>> 
>>>>> I cannot think of any good reason (other than inertia) for +initialize
>>>>> not to be inherited as it is on Mac OS X. It's incompatibilities like
>>>>> this that make it hard to recommend Objective-C. Does anyone else care
>>>>> about this?
>>>>> 
>>>>> - lc
>>>>> 
>>>>> 
>>>>> On Jan 21, 2006, at 1:31 PM, David Ayers wrote:
>>>>> 
>>>>>> Larry Campbell schrieb:
>>>>>>> On Jan 21, 2006, at 4:50 AM, David Ayers wrote:
>>>>>>> 
>>>>>>>> 
>>>>>>>> Have a look at this discussion:
>>>>>>>> 
>>>>>>>> http://lists.apple.com/archives/objc-language/2004/Mar/msg00006.html
>>>>>>>> 
>>>>>>>> Now, I'm no advocate of being different just for the sake of being
>>>>>>>> different, but I also think that '+load' and '+initialize' are simply
>>>>>>>> "special" wrt inheritance and guarantees on how/when they are
>>>>>>>> called and
>>>>>>>> I would assume that we would break code written for the FSF libobjc
>>>>>>>> runtime if FSF's libobjc started to inherit +initialize.
>>>>>>> 
>>>>>>> 
>>>>>>> However, I think that:
>>>>>>> 
>>>>>>> 1. The difference between FSF here and Apple is a trap for the unwary
>>>>>>> 2. It would be best to remove such traps when possible
>>>>>>> 3. Due to binary compatibility it's extremely unlikely Apple will
>>>>>>> change
>>>>>>> 4. There's no clear advantage to the FSF approach (or the Apple
>>>>>>> approach)
>>>>>> 
>>>>>> All of these points could be applied for most of the FSF libobjc API.
>>>>>> (E.g., did you know that the class pointer of an 'id' in FSF's libobjc
>>>>>> is called 'class_pointer' instead of 'isa'? But yes, I realize the
>>>>>> inconsistency that Object.h still uses 'isa' as the ivar name.)
>>>>>> 
>>>>>> The reasons are historical and I assume have to do with the reluctance
>>>>>> of NeXT to release their GCC modifications to ObjC in the first place.
>>>>>> I kind of doubt that the FSF wanted to make their libobjc incompatible,
>>>>>> but I don't know the details of what happened and they seem to diverge
>>>>>> quite a bit more than I would have expected... Anyway, now there is
>>>>>> code out there that relies on FSF's libobjc and we should consider
>>>>>> changes carefully.
>>>>>> 
>>>>>>> 5. If you really want to share initialization code with subclasses, you
>>>>>>> have to move such initialization code into a separate method, or
>>>>>>> subclasses have to call [super initialize]
>>>>>> 
>>>>>> Moving them to separate methods that get invoked by +initialize seems
>>>>>> like the most robust approach to me.
>>>>>> 
>>>>>>> So I think I would argue that FSF should consider changing; not
>>>>>>> precipitously, and with perhaps a way to override via an environment
>>>>>>> variable in case of compatibility bugs.
>>>>>> 
>>>>>> Well this is the type of discussion that the above mentioned list was
>>>>>> created for. I am personally undecided on the issue and would insure
>>>>>> that any code I write today would be portable. Even if it is decided to
>>>>>> change the GNU semantics I believe the earliest libobjc release would be
>>>>>> 4.2 (or possibly 4.3 depending on libobjc maintainers view this in light
>>>>>> of the pending switch to Stage 2 of gcc's trunk) and any code relying on
>>>>>> NeXT/Apple semantics would have to wait until that compiler version is
>>>>>> in wide spread use.
>>>>>> 
>>>>>>>> Note that if you actually invoked either +initialize or +load in a
>>>>>>>> true
>>>>>>>> method invocation, the normal inheritance techniques would be used.
>>>>>>>> But
>>>>>>>> be warned, code often is not prepared for multiple invocations of
>>>>>>>> these
>>>>>>>> methods and could break in strange ways (e.g. replacing objects/caches
>>>>>>>> which were meant to be initialized as singletons).
>>>>>>> 
>>>>>>> 
>>>>>>> Yes, sadly all my initialize methods now have to look like this:
>>>>>>> 
>>>>>>> + (void)initialize
>>>>>>> {
>>>>>>> if (self == [MyClass class]) {
>>>>>>> static BOOL inited = NO;
>>>>>>> if (!inited) {
>>>>>>> // do stuff
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>> 
>>>>>>> (This still doesn't help with category initialize, but I try to avoid
>>>>>>> categories and I've never tried category initialize)
>>>>>> 
>>>>>> Category +initialize is a different story all together. Please read
>>>>>> that thread closely and then maybe you can propose semantics that we can
>>>>>> be discussed on that list.
>>>>>> 
>>>>>> - Should a category be able to replace the +initialize implementation of
>>>>>> a class?
>>>>>> - Should it be sent if the category is loaded after the first method
>>>>>> (and therefor the initial +initialize invocation has already been
>>>>>> executed)?
>>>>>> - Should it only be sent on the first invocation of any method that the
>>>>>> particular category implements rather than any method the class
>>>>>> implements?
>>>>>> - What is the expected hit on standard runtime method invocations if you
>>>>>> have to do all that checking during method dispatch?
>>>>>> 
>>>>>> When I went through all of that, I decided that +initialize on a per
>>>>>> category basis can not give the guarantees I would like and stay
>>>>>> efficient at the same time. But maybe you have some new ideas.
>>>>>> 
>>>>>> Cheers,
>>>>>> David
>>> 
>>> 
>>> _______________________________________________
>>> Discuss-gnustep mailing list
>>> Discuss-gnustep@gnu.org
>>> https://lists.gnu.org/mailman/listinfo/discuss-gnustep
>> 
>> 
>> _______________________________________________
>> Discuss-gnustep mailing list
>> Discuss-gnustep@gnu.org
>> https://lists.gnu.org/mailman/listinfo/discuss-gnustep
> 
> --
> This email complies with ISO 3103
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]