On 19/04/2013, at 4:35 PM, Greg Parker <gpar...@apple.com> wrote:

> Another solution is to introduce a weak reference between the timer and your 
> controller. Create a helper class that holds a weak reference to your 
> Controller object.


Since Greg and I have offered the same solution, here's an implementation of it 
you could use:

Usage would be for your controller to alloc/init the helper/proxy (or use the 
convenience method and retain it) and then in its -dealloc method call 
-invalidate followed by -release.

// .h file:


#import <Foundation/Foundation.h>



@interface GCTimerTarget : NSObject
{
@private
        NSTimer*        mTimerRef;
        id                      mTrueTargetRef;
        SEL                     mSelector;
}

@property (nonatomic, assign) NSTimer*  timer;
@property (nonatomic, assign) id                        trueTarget;
@property (nonatomic, assign) SEL               selector;

+ (GCTimerTarget*)      scheduledTimerWithInterval:(NSTimeInterval) t 
target:(id) target selector:(SEL) selector repeats:(BOOL) repeats;

- (id)          initForTarget:(id) trueTarget selector:(SEL) selector;
- (void)                invalidate;

@end


/// .m file:

#import "GCTimerTarget.h"



@interface GCTimerTarget ()

- (void)        timerCallback:(NSTimer*) timer;

@end


#pragma mark -


@implementation GCTimerTarget

@synthesize timer = mTimerRef;
@synthesize trueTarget = mTrueTargetRef;
@synthesize selector = mSelector;



+ (GCTimerTarget*)      scheduledTimerWithInterval:(NSTimeInterval) t 
target:(id) target selector:(SEL) selector repeats:(BOOL) repeats
{
        // convenience method makes the proxy and adds a scheduled timer to it. 
This can be used instead of the equivalent NSTimer class method
        
        GCTimerTarget* tt = [[[self alloc] initForTarget:target 
selector:selector] autorelease];
        tt.timer = [NSTimer scheduledTimerWithTimeInterval:t target:tt 
selector:@selector(timerCallback:) userInfo:nil repeats:repeats];
        
        return tt;
}



- (id)                  initForTarget:(id) trueTarget selector:(SEL) selector
{
        self = [super init];
        if( self )
        {
                mTrueTargetRef = trueTarget;
                mSelector = selector;
        }
        
        return self;
}


- (void)                invalidate
{
        self.trueTarget = nil;
        [self.timer invalidate];
        self.timer = nil;
        
        // could call [self autorelease] here to make the proxy a one-line 
teardown, but it's probably safer to leave it as is
        // and rely on a deliberate -release as usual.
}


- (void)        timerCallback:(NSTimer*) timer
{
        if([self.trueTarget respondsToSelector:self.selector])
                [self.trueTarget performSelector:self.selector 
withObject:timer];
}


@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/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to