Just another angle on your original problem, have you considered using CFRetain and CFRelease on _myIvar? These are still meaningful in garbage collection mode. Using CFRetain when you get/create _myIvar, it would presumably still be alive in your finalize method until you call CFRelease on it.
-Eric On 3/9/12, [email protected] <[email protected]> wrote: >> >> On 8 Mar 2012, at 16:58, Quincey Morris wrote: >> >>> >>>> A more robust solution is a probably a separate -dispose method. >>> >>> Yes, though knowing when to call it can be a puzzle in itself, if there >>> are multiple references to the object. In general, you'll probably need >>> to invent a reference counting mechanism to keep track of when it's OK >>> for your dispose method to actually dispose of things. That sounds ironic >>> in a GC environment, but there's nothing wrong with reference counting >>> when you need to keep count. :) >> > > It turns out that chasing my objects around trying to figure out when to > safely dispose of their object resources is indeed a puzzle. > I have implemented the following category to provide a reference counting > mechanism for disposable resources. > Using a category makes it easy to add this functionality to an existing > class hierarchy. > > Some brief commentary and the code repo is at > http://github.com/mugginsoft/MGSDisposable > > Regards > > Jonathan Mitchell > Mugginsoft LLP > > #import <Foundation/Foundation.h> > > @interface NSObject (MGSDisposable) > > - (void)mgsMakeDisposable; > - (BOOL)isMgsDisposable; > - (NSUInteger)mgsDisposalCount; > - (BOOL)isMgsDisposed; > - (void)mgsRetainDisposable; > - (void)mgsReleaseDisposable; > - (void)mgsDispose; > - (BOOL)isMgsDisposedWithLogIfTrue; > - (void)mgsAssociateValue:(id)value withKey:(void *)key; > - (void)mgsWeaklyAssociateValue:(id)value withKey:(void *)key; > - (id)mgsAssociatedValueForKey:(void *)key; > - (void)mgsLogSelector:(SEL)sel; > @end > > #import "NSObject+MGSDisposable.h" > #import <objc/runtime.h> > > // enable logging > #define MGS_DISPOSAL_LOG > > // disable logging > // comment the line below to enable logging > #undef MGS_DISPOSAL_LOG > > static char mgsDisposableKey; > NSString * const MGSAllowDisposalKey = @"MGSAllowDisposal"; > NSString * const MGSAllowDisposaValue = @"Yes"; > > @implementation NSObject (MGSDisposable) > > /* > > - mgsMakeDisposable > > */ > - (void)mgsMakeDisposable > { > > #ifdef MGS_DISPOSAL_LOG > [self mgsLogSelector:_cmd]; > #endif > > // check if already disposable > if ([self isMgsDisposable]) { > return; > } > > // assign an initial reference count of 1 > NSNumber *refCount = [NSNumber numberWithUnsignedInteger:1]; > [self mgsAssociateValue:refCount withKey:&mgsDisposableKey]; > } > > /* > > - isMgsDisposable > > */ > - (BOOL)isMgsDisposable > { > return ([self mgsDisposalCount] == NSUIntegerMax ? NO : YES); > } > > /* > > - mgsDisposalCount > > */ > - (NSUInteger)mgsDisposalCount > { > NSNumber *refCount = [self mgsAssociatedValueForKey:&mgsDisposableKey]; > if (!refCount) { > return NSUIntegerMax; > } > > return [refCount unsignedIntegerValue]; > } > > /* > > - isMgsDisposed > > */ > - (BOOL)isMgsDisposed > { > NSUInteger refCount = [self mgsDisposalCount]; > return (refCount == 0 ? YES : NO); > } > > /* > > - mgsRetainDisposable > > */ > - (void)mgsRetainDisposable > { > > #ifdef MGS_DISPOSAL_LOG > [self mgsLogSelector:_cmd]; > #endif > > if (![self isMgsDisposable]) return; > if ([self isMgsDisposed]) return; > > NSUInteger refCount = [self mgsDisposalCount]; > if (refCount == NSUIntegerMax) { > return; > } > > [self mgsAssociateValue:[NSNumber numberWithUnsignedInteger:++refCount] > withKey:&mgsDisposableKey]; > } > > /* > > - mgsReleaseDisposable > > */ > - (void)mgsReleaseDisposable > { > > #ifdef MGS_DISPOSAL_LOG > [self mgsLogSelector:_cmd]; > #endif > > if (![self isMgsDisposable]) return; > if ([self isMgsDisposed]) return; > > NSUInteger refCount = [self mgsDisposalCount]; > if (refCount == NSUIntegerMax) { > return; > } > > // dispose when reference count == 1 > if (refCount == 1) { > [self mgsAssociateValue:MGSAllowDisposaValue > withKey:MGSAllowDisposalKey]; > [self mgsDispose]; > } else { > [self mgsAssociateValue:[NSNumber > numberWithUnsignedInteger:--refCount] withKey:&mgsDisposableKey]; > } > } > > /* > > - mgsDispose > > */ > - (void)mgsDispose > { > > #ifdef MGS_DISPOSAL_LOG > [self mgsLogSelector:_cmd]; > #endif > > // we must be disposable > if (![self isMgsDisposable]) return; > > // log and quit if already disposed > if ([self isMgsDisposedWithLogIfTrue]) return; > > // disposal is only valid when the allow disposal key is found > if (![self mgsAssociatedValueForKey:MGSAllowDisposalKey]) { > NSLog(@"Disposal is not valid at this time."); > return; > } > > // mark this object as disposed > [self mgsAssociateValue:[NSNumber numberWithUnsignedInteger:0] > withKey:&mgsDisposableKey]; > > // remove the allow disposal key > [self mgsAssociateValue:nil withKey:MGSAllowDisposalKey]; > } > > /* > > - isMgsDisposedWithLogIfTrue > > */ > - (BOOL)isMgsDisposedWithLogIfTrue > { > if (![self isMgsDisposable]) return NO; > > BOOL disposed = [self isMgsDisposed]; > if (disposed) { > NSLog(@"mgsDispose already called."); > } > > return disposed; > } > > /* > > - mgsAssociateValue > > */ > - (void)mgsAssociateValue:(id)value withKey:(void *)key > { > objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN); > } > > /* > > - mgsWeaklyAssociateValue > > */ > - (void)mgsWeaklyAssociateValue:(id)value withKey:(void *)key > { > objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_ASSIGN); > } > > /* > > - mgsAssociatedValueForKey > > */ > - (id)mgsAssociatedValueForKey:(void *)key > { > return objc_getAssociatedObject(self, key); > } > > /* > > - mgsLogSelector: > > */ > - (void)mgsLogSelector:(SEL)sel > { > NSLog(@"%@ received %@.", self, NSStringFromSelector(sel)); > } > > @end > > > _______________________________________________ > > Cocoa-dev mailing list ([email protected]) > > 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: > https://lists.apple.com/mailman/options/cocoa-dev/ewmailing%40gmail.com > > This email sent to [email protected] > -- Beginning iPhone Games Development http://playcontrol.net/iphonegamebook/ _______________________________________________ Cocoa-dev mailing list ([email protected]) 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: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [email protected]
