Re: Garbage Collection in Objective-C++
Re: Garbage Collection in Objective-C++
- Subject: Re: Garbage Collection in Objective-C++
- From: David Elliott <email@hidden>
- Date: Wed, 6 Feb 2008 01:52:03 -0500
Hi Chris,
This has nothing to do with solving my specific problem but I'll
respond anyway.
For what it's worth, the CFRetain/CFRelease you proposed worked
beautifully. Thank you. I've still got some remaining large issues
in GC mode but I'll hopefully be able to figure those out and/or post
a different message for those.
On Feb 5, 2008, at 11:50 PM, Chris Hanson wrote:
On Feb 5, 2008, at 8:39 PM, David Elliott wrote:
wxObjcAutoRefFromAlloc<void*> s_foo = [[[SomeClass alloc] init]
autorelease];
There is no NSAutoreleasePool during C++ static initialization time
so this is unworkable.
In this case, in fact, [[SomeClass alloc] init] is also unworkable
because you don't know what side-effects +[SomeClass load], +
[SomeClass initialize] or -[SomeClass init] -- or any similar
superclass methods -- will have.
Actually I know exactly what side-effects they will have since they
are my own simple NSObject-derived classes.
You can't mix C++ and Objective-C this way. Sorry.
I very much beg to differ. I'll have to dig it up again but somewhere
in the docs there is a guarantee that the Objective-C classes for any
given C++ file will already have had their load methods called before C
++ static initialization time occurs. So there is no problem with
doing what I'm doing other than Foundation preferring to be called
within the context of an NSAutoreleasePool which is not an issue when
I only call alloc and init on an object of my own class which only
involves foundation in the sense that it derives from NSObject and
thus calls its alloc and init methods which fortunately do not require
a pool.
In other words, assigning an object reference *to* one of these
should cause a retain.
I agree with you that your idea more closely follows Objective-C
semantics but it goes completely against C++ pointer-holder
semantics.
You're dealing with Objective-C code, so you need to follow its
conventions. One of these is that taking ownership generally either
retains or copies. Another is that you can't run code outside an
autorelease pool (when running on the non-GC runtime).
I see it more that I'm dealing with primarily C++ code that happens to
use Objective-C. As I said, my original idea was to follow Objective-
C conventions which became unworkable due to lack of an autorelease
pool. So I came up with the ...FromAlloc variant. But further
reflection has led me to the belief that a C++ pointer-holder should
have C++ pointer-holder semantics, even when the pointer being held
points to an Objective-C object.
No such semantics exist in Objective-C because Objective-C has nothing
like a C++ pointer-holder.
A much better class to look at in wx is the wxCFRef<refType> that I
wrote years later (i.e. a few months ago instead of a few years
ago). Like the standard library auto_ptr or TR1 shared_ptr it has
an explicit constructor from a pointer which assumes it is taking
ownership of the pointer.
"Taking ownership" of a Cocoa object means retaining it.
Let me put it to you this way:
SomeClass *aRawPtr = new SomeClass;
shared_ptr<SomeClass> aSharedPtr(aRawPtr);
This is now an error:
delete aRawPtr;
Therefore it follows that it makes sense for a C++ Objective-C pointer
holder for the following to be true:
SomeClass *aRawPtr = [[SomeClass alloc] init];
objc_ptr<SomeClass> anObjcPtr(aRawPtr);
This should be an error:
[aRawPtr release];
I understand why you're following the path you're on, but I really
think you're ultimately making things harder for yourself by doing
so. When working with Cocoa, you really do need to follow the Cocoa
patterns.
I can say the same that when working with C++ you really ought to
follow the C++ patterns. Obviously I wouldn't write an Objective-C
initializer that did not retain its argument when keeping a reference
in an i-var. Nor would I write a C++ constructor for a non-holder
object that did not retain. Nor would I write a setter method (even
in C++) that didn't retain/release.
As a simple example, consider the wxWindow::SetNSView() method. It
does in fact retain/release its argument as if it were an Objective-C
setter method.
So believe me when I say I am very keenly aware of the retain/release
semantics and that after thorough thought and experience with both
semantics I have decided that the traditional C++ pointer-holder
semantics are simply more appropriate for that one very-specific case.
Also note that the smart-pointer should not have a traditional
Objective-C getter/setter scheme for the same reason. It is not an
Objective-C object and it is not a C++ object trying to act similarly
to an Objective-C object. It is quite specifically a pointer-holder
and those have their own unique semantics (i.e. a get() method but
reset() instead of set()).
The pointer-holder is a concept that only exists in C++ and thus the
nature of the target pointer should not, in my experienced opinion,
change the semantics of the holder class.
-Dave
_______________________________________________
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