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, jonat...@mugginsoft.com <jonat...@mugginsoft.com> 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 (Cocoa-dev@lists.apple.com)
>
> 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 ewmail...@gmail.com
>


-- 
Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to