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:28:55 -0400

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




reply via email to

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