Thanks for your answers! Now I'm thinking that I'd rather create a helper category on NSTimer with a method that will schedule a timer but under the hood also create the helper object. In this way, the current code of my project will almost not change (only change the scheduling method). The helper class will be private. The helper will not be retained by anyone except the run loop and will be dealloced immediately after the timer is invalidated
@interface TimerHelper @property (nonatomic, assign) id target; @property (nonatomic, assign) SEL action; - (void)timerDidFire; @end @implementation TimerHelper - (void)timerDidFire { [_target performSelector:_action withObject:nil]; } @end @implementation NSTimer (Helper) + (NSTimer*)scheduleTimerWithInterval:(NSTimeInterval)interval target:(id)target action:(SEL)action { TimerHelper* helper = [[[TimerHelper alloc] init] autorelease]; helper.target = target; helper.action = action; NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:interval target:helper selector:@selector(timerDidFire) userInfo:nil repeats:YES]; return timer; } @end @implementation Controller { NSTimer* _timer; } - (void)someMethod { _timer = [[NSTimer scheduleTimerWithInterval:interval target:self action:@selector(someTimerDidFire)] retain]; } - (void)dealloc { [_timer invalidate]; [_timer release]; [super dealloc]; } @end I think this is a more elegant solution than public helper. Any caveats? On Fri, Apr 19, 2013 at 9:53 AM, Graham Cox <graham....@bigpond.com> wrote: > > 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