• 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: ivar access during -finalize
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ivar access during -finalize


  • Subject: Re: ivar access during -finalize
  • From: Eric Wing <email@hidden>
  • Date: Sat, 10 Mar 2012 14:51:59 -0800

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@hidden <email@hidden> 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@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
>


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

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: ivar access during -finalize
      • From: "email@hidden" <email@hidden>
References: 
 >ivar access during -finalize (From: "email@hidden" <email@hidden>)
 >Re: ivar access during -finalize (From: Quincey Morris <email@hidden>)
 >Re: ivar access during -finalize (From: "email@hidden" <email@hidden>)
 >Re: ivar access during -finalize (From: "email@hidden" <email@hidden>)

  • Prev by Date: Re: Was using SnowLeopard, Xcode 4.2, iOS 5.0.1... now storyboard won't update
  • Next by Date: Re: ivar access during -finalize
  • Previous by thread: Re: ivar access during -finalize
  • Next by thread: Re: ivar access during -finalize
  • Index(es):
    • Date
    • Thread