NSTimer с блоком - я делаю это правильно?
Ниже приведена моя категория Objective-C в NSTimer для блокировки NSTimers на основе блоков. Я не вижу ничего плохого в этом, но то, что я получаю, заключается в том, что блок, который я передаю в метод schedule...
, освобождается, несмотря на то, что я нахожу его copy
.
Что мне не хватает?
typedef void(^NSTimerFiredBlock)(NSTimer *timer);
@implementation NSTimer (MyExtension)
+ (void)timerFired:(NSTimer *)timer
{
NSTimerFiredBlock blk = timer.userInfo;
if (blk != nil) {
blk(timer);
}
}
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
repeats:(BOOL)repeats
callback:(NSTimerFiredBlock)blk
{
return [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:@selector(timerFired:)
userInfo:[blk copy]
repeats:repeats];
}
@end
Ответы
Ответ 1
Я нашел этот код в http://orion98mc.blogspot.ca/2012/08/objective-c-blocks-for-fun.html
Отличная работа
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.7
target:[NSBlockOperation blockOperationWithBlock:^{ /* do this! */ }]
selector:@selector(main)
userInfo:nil
repeats:NO
];
Ответ 2
У вас есть проект по github, который выполняет эту работу!
Cocoapod BlocksKit, позволяет блокировать кучу классов...
#import "NSTimer+BlocksKit.h"
[NSTimer bk_scheduledTimerWithTimeInterval:1.0 block:^(NSTimer *time) {
// your code
} repeats:YES];
Ответ 3
То, что вам не хватает, заключается в том, что если блок, который вы проходите, находится в стеке, тогда copy
будет делать то, что имя говорит, - это создаст копию блока над кучей. Поэтому вы не ожидаете изменений в поведении того, с которым вы проходили; никто не сохраняет его. Копия останется в живых, пока оригинал не освобожден.
(в остальном: если вы не используете ARC, вы также захотите автоповторить копию, вы должны передать ссылку без прав на userInfo:
. В противном случае копия никогда не будет освобождена)
Ответ 4
Вот версия Swift Ответ Mc.Stever:
NSTimer.scheduledTimerWithTimeInterval(0.7, target: NSBlockOperation(block: {
/* do work */
}), selector: "main", userInfo: nil, repeats: false)
Ответ 5
попробуйте это
typedef void(^NSTimerFiredBlock)(NSTimer *timer);
@interface NSObject (BlocksAdditions)
- (void)my_callBlock:(NSTimer *)timer;
@end
@implementation NSObject (BlocksAdditions)
- (void)my_callBlock:(NSTimer *)timer {
NSTimerFiredBlock block = (id)self;
block(timer);
}
@implementation NSTimer (MyExtension)
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
repeats:(BOOL)repeats
callback:(NSTimerFiredBlock)blk
{
blk = [[blk copy] autorelease];
return [NSTimer scheduledTimerWithTimeInterval:seconds
target:blk
selector:@selector(my_callBlock:)
userInfo:nil
repeats:repeats];
}
@end