• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Garbage Collection in Objective-C++
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Garbage Collection in Objective-C++


  • Subject: Re: Garbage Collection in Objective-C++
  • From: David Elliott <email@hidden>
  • Date: Tue, 5 Feb 2008 23:39:47 -0500

Hi Chris,

On Feb 5, 2008, at 11:09 PM, Chris Hanson wrote:

On Feb 5, 2008, at 6:53 PM, David Elliott wrote:

wxObjcAutoRefFromAlloc<void*> s_foo = [[SomeClass alloc] init];

The idea is that wxObjcAutoRefFromAlloc constructs with an already- retained object (e.g. one from alloc) and releases on destruction. Copy construction results in a retain so that's not an issue. Ignore that class for now though as the implementation of it is horrible, so don't go looking it up.


Really, I think the main issue with what you're trying to do is expressed above.

(1) You're assigning an object reference to something that's typed (effectively) as "void *" so you're pretty much hiding the object reference from the collector.

Perhaps I wasn't clear that I changed the code to use id instead of void* which DID cause the objc_assign_strongCast to be emitted. But it doesn't work because the compiler is emitting the wxObjcAutoRefFromAlloc constructor sort of like this:

wxObjcAutoRefFromAlloc(T ptr)
{
    objc_assign_strongCast(ptr, &m_ptr);
}

This appears to work fine so long as the wxObjcAutoRefFromAlloc object is allocated on the heap. If it is allocated in the global data area then the strongCast is completely ignored. The compiler can of course not know this information when generating the constructor for wxObjcAutoRefFromAlloc which is I believe the fundamental problem here.

(2) You're using different memory management semantics than normal, by expecting the initial -retain sent to the object reference to come from "outside" the object you're passing it to.

No, I'm using memory management semantics appropriate for C++ pointer- holders. See below.

You can change #2 so that the above line of code under non-GC would read like this:

wxObjcAutoRefFromAlloc<void*> s_foo = [[[SomeClass alloc] init] autorelease];


There is no NSAutoreleasePool during C++ static initialization time so this is unworkable.


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.


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.

This semantic was at the behest of Stefan Csomor (the wxMac author) and I decided that he was very right about it. More often than not you are creating the wxCFRef from a CF Create* method and if you got it from a Get* method instead then you can simply use the following pattern:

wxCFRef<CFStringRef> myString(CFRetain(CFSomethingElseGetSomeString(somethingElse)));

The "gotcha" is that constructing from the raw pointer and that copy- constructing from another ref have different semantics. However, the same is true of shared_ptr in exactly the same way and thus from a C++ programmer's point of view the disparity makes perfect sense.

A similar situation occurs in Objective-C. When you are using these C+ + pointer holders more often than not you are allocating the object yourself and thus it is already retained. Should you not have a reference to it you should retain it on the Objective-C side like this:

wxNewStyleObjcRef<NSString*> myString([[SomeControl stringValue] retain]);

I realize it rightly offends your Objective-C sensibilities but looking back on it, the wxObjcAutoRef class should never have existed and the semantics used by wxObjcAutoRefFromAlloc should have been the only ones available. My mistake in writing the original wxObjcAutoRef/ wxObjcAutoRefFromAlloc was to assume the Objective-C semantics were appropriate.

Then, once your wxObjcAutoRefFromAlloc<T> class retains on assignment, you can convert it from sending -retain and -release to instead call the CFRetain and CFRelease functions. These effectively add and remove a root under GC, and they will cause - retain and -release to be sent under non-GC, so you should get correct behavior in all circumstances.

Ok, now that is an interesting and very workable idea. I did not realize that it was safe to call CFRetain/CFRelease on all Objective-C objects. I thought it only applied to those that were explicitly toll- free bridged. If this is the case then it would seem I'd want to declare the C++ i-var as weak (thus avoid objc_assign_strongCast from the compiler) and use explicit CFRetain/CFRelease. Will this work on older OS X as well or only on more recent versions?

I will probably have to adjust this to [(id)CFRetain(ptr) release]; to keep my C++ pointer-holder semantics but that should still be workable as under non-GC mode it boils down to retain/release (e.g. no-op) thus keeping the ref count at 1 (from the alloc) which will be balanced by the CFRelease (e.g. regular release) in the destructor. In GC mode it does a forceful CFRetain and a release no-op which will be balanced by the CFRelease.

-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


  • Follow-Ups:
    • Re: Garbage Collection in Objective-C++
      • From: Chris Hanson <email@hidden>
References: 
 >Garbage Collection in Objective-C++ (From: David Elliott <email@hidden>)
 >Re: Garbage Collection in Objective-C++ (From: Chris Hanson <email@hidden>)

  • Prev by Date: Re: Garbage Collection in Objective-C++
  • Next by Date: Re: Garbage Collection in Objective-C++
  • Previous by thread: Re: Garbage Collection in Objective-C++
  • Next by thread: Re: Garbage Collection in Objective-C++
  • Index(es):
    • Date
    • Thread