[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Why is +initialize not inherited?
From: |
David Chisnall |
Subject: |
Re: Why is +initialize not inherited? |
Date: |
Thu, 15 Sep 2011 19:43:53 +0100 |
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