NSTimer Kategorie + Blöcke Implementierung zu ersetzen selector
Ich bin ganz neu auf Blöcke und objective-c, und ich bin versucht zu schreiben, meine ersten Kategorie mit beiden. Meine Idee ist das erstellen einer Kategorie auf NSTimer, der erhält einen block als parameter, und dieser block wird verwendet in der Selektor-Aufruf. Jetzt habe ich diese.
//NSTimer+Additions.h
#import <Foundation/Foundation.h>
typedef void (^VoidBlock)();
@interface NSTimer (NSTimer_Additions)
+ (NSTimer *)scheduleTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions;
@end
#import "NSTimer+Additions.h"
static VoidBlock _voidBlock;
@interface NSTimer (AdditionsPrivate) //Private stuff
- (void)theBlock;
@end
@implementation NSTimer (NSTimer_Additions)
+ (NSTimer *)scheduleTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions {
[_voidBlock release];
_voidBlock = [actions copy];
NSTimer* timer = [[NSTimer alloc] initWithFireDate:[NSDate date]
interval:theSeconds
target:self
selector:@selector(theBlock)
userInfo:nil
repeats:repeats];
[timer fire];
return [timer autorelease];
}
- (void)theBlock {
_voidBlock();
}
@end
Kern für den code: https://gist.github.com/1065235
Alles kompiliert einwandfrei, aber ich habe den folgenden Fehler:
2011-07-05 14:35:47.068 TesteTimer[37716:903] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSTimer theBlock]: unrecognized selector geschickt-Klasse 0x7fff70bb0a18'
Wie kann ich diese Kategorie Arbeit?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihren großen Makel neben dem Ziel falsch ist Ihre Verwendung einer statischen variable. Sie werden nicht in der Lage zu unterstützen, über einen einzigen timer.
Using-block als argument an die aufgerufene Methode.
Das problem bei der Verwendung von assoziativen Verweise war das Leck als es war kein guter Zeitpunkt zum lösen der Sperrung.
Früheren Ansatz, bei dem assoziative Verweise
Können Sie
assoziative Verweise
befestigen Sie den block auf die jeweilige Instanz vonNSTimer
.actions = Block_copy(actions);
oderactions = [actions copy];
weilcopy
nicht immer wieder das gleiche Objekt. Außerdem müssen Sie tun[invocation retainArguments];
weil es sonst nicht aufbewahrt werden, durch die Anrufung.Was um die Nutzung userInfo tragen Ihrem block? (dies geschieht mit ARC)
Und fügen Sie den statischen Wähler:
Sollte dies funktionieren:
Das problem ist, dass Sie das Ziel des neuen
NSTimer
Instanzself
. Aber im Kontext der+ scheduleTimerWithTimeInterval:repeats:actions:
(beachten Sie die+
),self
istNSTimer
, und nicht (wie Sie wohl dachte) Ihre neu erstellteNSTimer
Instanz.Sehen Sie die Fehlermeldung, die app abstürzt, weil
NSTimer
reagiert nicht auf die Methode der Klasse+ theBlock
, das ist natürlich korrekt, da Sie nur die Instanz-Methode- theBlock
.