Die [NSTimer scheduledTimerWithTimeInterval:...]
behält sich das Ziel, so dass, wenn das Ziel Selbst, dann Instanz der Modellklasse wird nie freigegeben werden.
Als Workaround kann ein separates Objekt verwendet werden (im folgenden Beispiel TimerTarget
). TimerTarget
hat eine schwache Referenz auf ModelClass
, um einen Retain-Zyklus zu vermeiden.
Diese "Helferklasse" sieht so aus. Der einzige Zweck besteht darin, das Timer-Ereignis an das "echte Ziel" weiterzuleiten.
@interface TimerTarget : NSObject
@property(weak, nonatomic) id realTarget;
@end
@implementation TimerTarget
- (void)timerFired:(NSTimer*)theTimer
{
[self.realTarget performSelector:@selector(timerFired:) withObject:theTimer];
}
@end
nun in Ihrem Modell-Klasse können Sie einen Timer erstellen und ungültig machen es in dealloc
:
@interface ModelClass()
@property(strong, nonatomic) NSTimer *timer;
@end
@implementation ModelClass
- (id)init
{
self = [super init];
if (self) {
TimerTarget *timerTarget = [[TimerTarget alloc] init];
timerTarget.realTarget = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:timerTarget
selector:@selector(timerFired:)
userInfo:nil repeats:YES];
}
return self;
}
- (void)dealloc
{
[self.timer invalidate]; // This releases the TimerTarget as well!
NSLog(@"ModelClass dealloc");
}
- (void)timerFired:(NSTimer*)theTimer
{
NSLog(@"Timer fired");
}
@end
So haben wir
modelInstance ===> timer ===> timerTarget ---> modelInstance
(===> : strong reference, ---> : weak reference)
Hinweis, dass es keine (starken) Referenz vom Timer auf die Instanz der Modellklasse.
Ich habe dies mit dem folgenden Code getestet, die eine Instanz von ModelClass
und gibt sie nach 5 Sekunden erstellt:
__block ModelClass *modelInstance = [[ModelClass alloc] init];
int64_t delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
modelInstance = nil;
});
Ausgang: Idee
2013-01-23 23:54:11.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:12.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:13.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:14.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:15.483 timertest[16576:c07] Timer fired
2013-01-23 23:54:15.484 timertest[16576:c07] ModelClass dealloc
Ich habe das wirklich noch nie benutzt ... Als ich Objective-C wurde das Lernen gesagt, ich war immer, dass 'dealloc' selten mehr verwendet wird. Werden meine Eigenschaften in der Dealloc-Methode noch gültig sein? – Nosrettap
Wie wäre es mit dealloc? Ja, werden sie sein. Ich tippe es als Antwort ein. –
Cool! Wenn Sie dies als Antwort posten, akzeptiere ich es – Nosrettap